/// <summary> /// 增加获取分布式锁请求 /// 主要用于多个线程同时获取同一个couchbase缓存key的加锁数据,将并发转换成队列等待的回调方式处理 /// </summary> /// <param name="key">couchbase缓存key</param> /// <param name="getLockTimeOut">获取锁的超时时间,单位:ms</param> /// <param name="lockTimeOut">持有锁的时间,单位:ms</param> /// <param name="action">获取到加锁的数据回调事件</param> /// <param name="cancelToken">等待线程取消通知,用于取消当前线程获取加锁数据操作</param> private void AddGetWithLockRequest(string key, int getLockTimeOut, int lockTimeOut, Action <IOperationResult <object> > action, CancellationToken cancelToken, string bucketName) { ThreadQueue threadQueue; if (!_keyThreadQueue.TryGetValue(key, out threadQueue)) { lock (_keyThreadQueueLock) { if (!_keyThreadQueue.TryGetValue(key, out threadQueue)) { threadQueue = new ThreadQueue { HasProcessThread = false, WaitQueue = new ConcurrentQueue <CanCancelCallback>() }; var addResult = _keyThreadQueue.TryAdd(key, threadQueue); Log.Write(string.Format("添加key:({0})的等待队列,状态:{1}", key, addResult), MessageType.Info, GetType()); } } } threadQueue.WaitQueue.Enqueue(new CanCancelCallback { Callback = action, CancelToken = cancelToken }); if (!threadQueue.HasProcessThread) { lock (threadQueue) { if (!threadQueue.HasProcessThread) { CreateThreadForCacheKey(key, getLockTimeOut, lockTimeOut, threadQueue, bucketName); } } } }
/// <summary> /// 创建一个线程用于处理获取当前Couchbase缓存key的分布式缓存锁的线程队列 /// <para>多个线程需要获取同一个Couchbase缓存key的分布式锁,将这些线程排队,使用一个新线程对这些排队的线程进程处理</para> /// </summary> /// <param name="key">couchbase缓存key</param> /// <param name="getLockTimeOut">获取锁的超时时间,单位:ms</param> /// <param name="lockTimeOut">持有锁的时间,单位:ms</param> /// <param name="threadQueue">等待获取当前Couchbase缓存key的分布式缓存锁的线程队列</param> private void CreateThreadForCacheKey(string key, int getLockTimeOut, int lockTimeOut, ThreadQueue threadQueue, string bucketName) { Action action = () => { threadQueue.HasProcessThread = true; try { while (!threadQueue.WaitQueue.IsEmpty) { CanCancelCallback queueItem; if (!threadQueue.WaitQueue.TryDequeue(out queueItem) || queueItem == null || queueItem.Callback == null || queueItem.CancelToken.IsCancellationRequested) { Log.Write(string.Format("获取分布式锁的线程被跳过,key:{0},queueItem 为null:{1},queueItem.Callback 为null:{2}, queueItem.CancelToken.IsCancellationRequested:{3}", key, queueItem == null, queueItem == null || queueItem.Callback == null, queueItem == null || queueItem.CancelToken.IsCancellationRequested) , MessageType.Warn, GetType()); continue; } Log.Write(string.Format("处理获取分布式锁,key:{0}", key), MessageType.Debug, GetType()); ProcessGetWithLock(key, getLockTimeOut, lockTimeOut, queueItem, bucketName); } } finally { threadQueue.HasProcessThread = false; } }; _getCASTaskPool.AddTask(states => { action(); }, null); }