msdn:什么是“线程安全”?

时间:2010-06-29 04:48:27

标签: c# .net thread-safety

在许多MSDN文档中,这是在Thread Safety标题下编写的;

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

例如

; here

有人可以用一种相当简单的方式解释它吗? 谢谢:))

4 个答案:

答案 0 :(得分:12)

Eric Lippert对此有一个很好的blog post。基本上它本身就毫无意义。

我个人认为,当我看到锅炉板时,我不太相信MSDN。它并不总是意味着它所说的。例如,它对Encoding说了同样的事情 - 尽管事实上我们都使用来自多个线程的编码。

除非我有任何理由不相信(我使用Encoding),我假设我可以从没有全局状态损坏的任何线程调用任何静态成员。如果我想从不同的线程使用相同对象的实例成员,我认为如果我确保 - 通过锁定 - 一次只有一个线程将使用该对象,那就没关系。 (当然并非总是这样。有些对象具有线程关联性并且主动不喜欢从多个线程中使用,即使锁定到位.UI控件就是明显的例子。)

当然,如果对象被不明显地共享变得棘手 - 如果我有两个对象,每个对象共享一个对第三个的引用,那么我可能最终使用前两个对象独立于不同的线程,所有正确的锁定 - 但最终还是会破坏第三个物体。

如果类型 宣传自己是线程安全的,我希望它会提供一些有关它的细节。如果它是不可变的那么很容易 - 你可以只使用你喜欢的实例而不用担心它们。它是部分或全部“线程安全”类型,在细节非常重要的情况下是可变的。

答案 1 :(得分:5)

您可以同时从多个线程访问该类的任何公共静态成员,而不会中断该类的状态。如果多个线程同时尝试使用实例方法(那些未标记为“静态”的方法)访问该对象,则该对象可能会损坏。

如果尝试同时从多个线程访问同一个类的实例导致问题,则该类是“线程安全的”。

答案 2 :(得分:4)

一个“线程安全”的对象意味着如果两个线程在同一时间(或者非常接近,在单CPU系统上)使用它,那么它就不会被所述访问破坏。这通常是通过获取和释放可能导致瓶颈的锁来实现的,因此“线程安全”也可能意味着“缓慢”,如果它不需要的话就会完成。

非常期望公共静态成员在线程之间共享(注意,VB甚至调用它“共享”),因此公共静态通常以这样的方式制作,即它们可以安全地使用

实例成员通常不是线程安全的,因为在一般情况下它会减慢速度。因此,如果您想要在线程之间共享一个对象,则需要进行自己的同步/锁定。

答案 3 :(得分:0)

要理解这一点,请考虑以下示例。 在.net类HashSet的MSDN描述中,有一个部分说明了线程安全性。对于HashSet类,MSDN说“此类型的任何公共静态(在Visual Basic中共享)成员都是线程安全的。任何实例成员都不能保证是线程安全的。“ 因为我们都知道竞争条件和死锁的概念,但微软想用简单的英语说什么呢? 如果两个线程将两个值添加到HashSet的“实例”中,则存在一些我们可以将其计数为一的情况。原因是在这种情况下HashSet对象已损坏,因为我们现在在HashSet中有两个对象,但它的计数只显示一个。但是,即使两个线程同时添加值,HashSet的公共静态版本也不会面临这样的损坏。