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>实际上并没有任何静态成员).实例成员类似于Enqueue和Dequeue- 与类型实例相关的成员而不是类型本身.
因此,您需要为每个操作使用锁定,或者如果您使用的是.NET 4,请使用ConcurrentQueue<T>.