这是否使用静态队列线程安全?

bli*_*sta 9 .net c# thread-safety

msdn文档声明静态通用队列是线程安全的.这是否意味着以下代码是线程安全的?换句话说,当一个线程将一个int排队并且另一个线程同时使一个int出局时是否存在问题?我是否必须为线程安全锁定Enqueue和Dequeue操作?

class Test {
    public static Queue<int> queue = new Queue<int>(10000);

    Thread putIntThread;
    Thread takeIntThread;

    public Test() {
        for(int i = 0; i < 5000; ++i) {
            queue.Enqueue(0);
        }
        putIntThread = new Thread(this.PutInt);
        takeIntThread = new Thread(this.TakeInt);
        putIntThread.Start();
        takeIntThread.Start();
    }

    void PutInt() {
        while(true)
        {
            if(queue.Count < 10000) {//no need to lock here as only itself can change this condition
                queue.Enqueue(0);
            }
        }
    }

    void TakeInt() {
        while(true) {
            if(queue.Count > 0) {//no need to lock here as only itself can change this condition
                queue.Dequeue();
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

编辑:我必须使用.NET 3.5

Jon*_*eet 23

这绝对不是线程安全的.来自的文档Queue<T>.

此类型的公共静态(在Visual Basic中为Shared)成员是线程安全的.任何实例成员都不保证是线程安全的.

A Queue<T>可以同时支持多个读取器,只要不修改集合即可.即便如此,通过集合枚举本质上不是一个线程安全的过程.为了在枚举期间保证线程安全,您可以在整个枚举期间锁定集合.要允许多个线程访问集合以进行读写,您必须实现自己的同步.

重读你的问题,你似乎对短语"这种类型的静态成员"感到困惑 - 它不是在谈论"静态队列",因为没有这样的东西.对象不是静态的或不是 - 成员是.当谈到静态成员时,它谈论的事情Encoding.GetEncoding(Queue<T>实际上并没有任何静态成员).实例成员类似于EnqueueDequeue- 与类型实例相关的成员而不是类型本身.

因此,您需要为每个操作使用锁定,或者如果您使用的是.NET 4,请使用ConcurrentQueue<T>.