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

从以下网站:

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

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

是什么让List<T>不是线程安全的? .NET框架工程师的实现问题? 或者generics不是线程安全的?

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

但是,Java的向量的有用性是有限的multithreading没有额外的同步。 例如,考虑从vector中读取元素的简单行为

 Vector vector = getVector(); if ( vector.size() > 0 ) { object first = vector.get(0); } 

这种方法不会破坏vector的状态,但也是不正确的。 在if语句和get()调用之间,没有任何东西阻止另一个线程在向量之间进行变异。 由于竞争条件,此代码最终可能失败。

这种types的同步只是在方便的情况下才有用,而且肯定不便宜。 即使您不使用多个线程,也需要付出可观的同步价格。

.netselect不支付这个价格默认情况下只有有限的情况。 相反,它select了实现一个无锁的列表。 作者负责添加任何同步。 这更接近于C ++的“只为你使用的东西付费”

我最近写了一些关于使用集合的危险的文章,只有内部同步,比如Java的向量。

  • 为什么线程安全的集合这么难?
  • 一个可变的线程安全集合更可用的API

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

为什么它是线程安全的? 并不是每个class级都是。 事实上,默认情况下,类不是线程安全的。

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

这只是一个devise决定,实现不是线程安全的types。 这些集合为某些集合提供了接口ICollection的属性SyncRootSynchronized()方法,用于显式同步数据types。

使用SyncRootlockingmultithreading环境中的对象。

 lock (collection.SyncRoot) { DoSomething(collection); } 

使用collection.Synchronized()获取collection.Synchronized()的线程安全包装器。

JaredPar提到的竞争条件可能性是依赖Vector的线程安全性的可怕后果。 这种情况会导致“每个星期二的应用程序都会出现一些奇怪的现象”,这些缺陷报告会让你疯狂。

在.NET 4中有很多真正的线程安全的集合,它们有一个有趣的副作用,它们允许枚举时对集合进行单线程修改 ,但是线程安全性有时会带来性能上的打击大的一个。

所以对于框架开发人员来说,合乎逻辑的事情是让95%的用户可能不会进行线程化,并依靠那些使用multithreading的用户来了解他们必须做些什么它安全。

为了真正的线程安全, List<>和其他集合types需要是不可变的。 .NET 4.0的并行扩展出现在.NET 4.0中,我们将看到最常用集合的线程安全版本。 Jon Skeet谈到了这一点。

使用SynchronizedCollection它也提供了一个使用共享同步的构造函数参数:)