从以下网站:
http://crfdesign.net/programming/top-10-differences-between-java-and-c
不幸的是,
List<>
它不是线程安全的(C#ArrayList
和 JavaVector
是线程安全的)。C# 也有一个Hashtable
; 通用版本是:
是什么让List<T>
线程不安全?是.NET框架工程师的实现问题吗?还是泛型不是线程安全的?
从以下网站:
http://crfdesign.net/programming/top-10-differences-between-java-and-c
不幸的是,
List<>
它不是线程安全的(C#ArrayList
和 JavaVector
是线程安全的)。C# 也有一个Hashtable
; 通用版本是:
是什么让List<T>
线程不安全?是.NET框架工程师的实现问题吗?还是泛型不是线程安全的?
您确实需要对 Java 的 Vector 的线程安全类型进行分类。Javas Vector 可以安全地从多个线程中使用,因为它在方法上使用同步。状态不会被破坏。
但是,Java 的向量的用处受限于没有额外同步的多线程。例如,考虑从向量中读取元素的简单行为
Vector vector = getVector();
if ( vector.size() > 0 ) {
object first = vector.get(0);
}
这种方法不会破坏向量的状态,但也是不正确的。没有什么可以阻止另一个线程在 if 语句和 get() 调用之间改变向量。由于竞争条件,此代码可能并且最终会失败。
这种类型的同步只在少数情况下有用,而且肯定不便宜。即使您不使用多个线程,您也需要为同步付出可观的代价。
.Net 选择默认不支付这个价格,因为它的用处有限。相反,它选择实现一个无锁列表。作者负责添加任何同步。它更接近 C++ 的“只为你使用的东西付费”的模型
我最近写了几篇关于使用只有内部同步的集合(如 Java 的向量)的危险的文章。
参考 Vector 线程安全:http ://www.ibm.com/developerworks/java/library/j-jtp09263.html
为什么它是线程安全的?不是每个班级都是。事实上,默认情况下,类不是线程安全的。
线程安全意味着任何修改列表的操作都需要互锁以防止同时访问。即使对于那些只会被单个线程使用的列表,这也是必要的。那将是非常低效的。
实现非线程安全的类型只是一个设计决定。集合提供SyncRoot
接口的属性ICollection
和Synchronized()
一些集合的方法,用于显式同步数据类型。
用于SyncRoot
在多线程环境中锁定对象。
lock (collection.SyncRoot)
{
DoSomething(collection);
}
用于collection.Synchronized()
获取集合的线程安全包装器。
为了真正的线程安全,List<>
其他集合类型需要是不可变的。随着 .NET 4.0 中出现的 .NET 并行扩展,我们将看到最常用集合的线程安全版本。
Jon Skeet 谈到了其中的一些内容。
使用 SynchronizedCollection 它还提供了一个构造函数参数来使用共享同步:)