为什么List <T>不是线程安全的?

Hao*_*Hao 42 .net generics thread-safety

从以下网站:

http://crfdesign.net/programming/top-10-differences-between-java-and-c

不幸的是,List<>它不是线程安全的(C#ArrayList和Java Vector是线程安全的).C#也有一个Hashtable; 通用版本是:

什么使List<T>线程不安全?它是.NET框架工程师的实现问题吗?或者泛型不是线程安全的吗?

Jar*_*Par 67

您确实需要对Java的Vector类型的线程安全性进行分类.Javas Vector可以安全地从多个线程使用,因为它在方法上使用同步.国家不会被腐败.

但是,Java的向量的有用性受限于多个线程而没有额外的同步.例如,考虑从向量中读取元素的简单行为

Vector vector = getVector();
if ( vector.size() > 0 ) { 
  object first = vector.get(0);
}
Run Code Online (Sandbox Code Playgroud)

此方法不会破坏向量的状态,但也不正确.没有什么能阻止另一个线程在if语句和get()调用之间改变向量.此代码可以和最终失败的原因的竞争条件.

这种类型的同步仅在一些场景中有用,并且它当然不便宜.即使您不使用多个线程,也要为同步支付明显的价格.

对于只有有限用途的场景,.Net选择不支付此价格.相反,它选择实现无锁定列表.作者负责添加任何同步.它更接近C++的"仅为你使用的东西付费"的模式

我最近写了几篇关于使用只有内部同步的集合的危险的文章,比如Java的vector.

参考Vector线程安全:http://www.ibm.com/developerworks/java/library/j-jtp09263.html

  • 小记:"无锁"意味着"没有任何锁定同步",而不是"无锁".http://en.wikipedia.org/wiki/Lock_free (13认同)

Joh*_*ers 20

为什么它是线程安全的?不是每个班级都是.实际上,默认情况下,类不是线程安全的.

线程安全意味着修改列表的任何操作都需要与同时访问互锁.即使对于那些只能由单个线程使用的列表,这也是必要的.那将是非常低效的.


Dan*_*ner 9

实现不是线程安全的类型只是一个设计决策.集合提供了SyncRoot接口的属性ICollection以及Synchronized()某些集合上的方法,用于显式同步数据类型.

用于SyncRoot在多线程环境中锁定对象.

lock (collection.SyncRoot)
{
   DoSomething(collection);
}
Run Code Online (Sandbox Code Playgroud)

使用collection.Synchronized()以获得集合的线程安全的包装.

  • 请参阅JaredPar的文章,了解为何这几乎肯定不是您想要做的. (4认同)