1 public class DoubleCacheQueue<T> 2 { 3 4 public DoubleCacheQueue() 5 { } 6 public T Dequeue() 7 { 8 T t = default(T); 9 10 if (readQueue.Count > 0) 11 t= readQueue.Dequeue(); 12 else 13 { 14 writeQueue = Interlocked.Exchange<Queue<T>>(ref readQueue, writeQueue); 15 } 16 return t; 17 } 18 public void Enqueue(T item) 19 { 20 writeQueue.Enqueue(item); 21 } 22 23 public int Count 24 { 25 get { return readQueue.Count; } 26 } 27 //读缓冲 28 private Queue<T> readQueue = new Queue<T>(); 29 //写缓冲 30 private Queue<T> writeQueue = new Queue<T>(); 31 32 }
补充下: 我应用的场景就是只有2个线程,我想实现一个lock free的队列 一个读线程不停的Dequeue 一个写线程不停的Enqueue 在只有2个线程一个单线程读和一个单线程写的情况下,能不能双线程安全?
MSDN说的很清楚了,Queue的Item如果是公共静态的就是线程安全的。否则自己保证。
Queue本身不保证枚举的线程安全。so 你这么做不是线程安全的。
可以考虑用ConcurrentQueue<T> 类或者使用synchronized方法。
我很奇怪,你们都不看代码的么,我代码里面用到的是俩个Queue,一个读,一个写,读写分离的。单Queue本身不是线程安全这个前提我当然知道。
@garry:
看了啊,在极端的情况下你的读的线程可能永远读不到值。因为你写实际是先写到线程的LocalMemeray。读线程也是读自己的LocalMemeray。
具体见这个帖子:
http://www.cnblogs.com/bibiKu/archive/2013/02/19/2917161.html
见“线程通信模式”一节。
这个类我知道啊,我只是想搞明白上面的那个有没有线程安全问题
@garry:
public virtual object Dequeue() { if (this.Count == 0) { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EmptyQueue")); } object obj2 = this._array[this._head]; this._array[this._head] = null; this._head = (this._head + 1) % this._array.Length; this._size--; this._version++; return obj2; } public virtual void Enqueue(object obj) { if (this._size == this._array.Length) { int capacity = (int) ((this._array.Length * this._growFactor) / 100L); if (capacity < (this._array.Length + 4)) { capacity = this._array.Length + 4; } this.SetCapacity(capacity); } this._array[this._tail] = obj; this._tail = (this._tail + 1) % this._array.Length; this._size++; this._version++; }
帮你看了下内部代码,
1、他们使用了公用资源 this._head和this._tail 。
2、这两个方法没有临界区
3、这两个变量的计算没有使用原子操作
所以,多线程使用这两个方法会出现并发问题。
@滴答的雨:
我代码里面用到的是俩个Queue,一个读,一个写,读写分离,我要确认的是在读写切换的临界区这样做是不是线程安全的