哪些function使类成为线程安全的?

在MSDN中,一些.NET类描述如下:

这种类型是线程安全的。

要么

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

我的问题是哪些function使类成为线程安全的?

  • 线程安全编程是否有任何标准,建议或指南?

  • 当我使用lock(C#)关键字时,这意味着我的类是否是线程安全的?

  • 如何评估一个类的线程安全性? 是否有任何测试可以确保一个类是100%线程安全的?

例:

public class MyClass { public void Method() { lock (this) { // Now, is my class 100% thread-safe like Microsoft classes? } } type m_member1; type m_member2; } 

谢谢

如果一个类可以被多个线程同时调用而不会破坏类的状态或导致意外的副作用,那么它通常被认为是线程安全的。 一个类可能不是线程安全的原因有很多,尽管一些常见的原因是它包含一些在并发访问时会被破坏的状态。

有许多方法可以使类成为线程安全的:

  1. 使其成为不可变的,如果一个类不包含任何状态,则可以安全地从多个线程同时使用它。
  2. 使用锁定来减少并发性。 但是,这并不保证线程安全,它只是确保多个线程不会同时执行代码块。 如果状态存储在方法调用之间,则可能仍然会变得不一致。

如何创建一个线程安全的类实际上取决于你想对这个类做什么。

你还需要问自己,我是否需要让我的课程线程安全? 大多数UI框架的通用模型是有一个UI线程。 例如,在WinForms,WPF和Silverlight中,大部分代码都将从UI线程执行,这意味着您不必在类中构建线程安全性。

线程安全编程是否有任何标准,建议或指南?

最重要的标准是确保所有静态成员都是线程安全的。 您将看到所有编写良好的API(包括.NET基类库)都可以全面保证这一点。 这有一个很好的理由。 由于静态成员在AppDomain中共享,因此许多不同的线程都可以使用它们,而您甚至无法实现它。 最好为每个静态成员访问提供自己的同步是很尴尬的。 想象一下如果Console.WriteLine不是线程安全的话会是什么样子。

就建议和指南而言,有许多完善的并行编程模式。 那里的模式涵盖了各种各样的编程问题,并使用了许多不同的同步机制。 生产者 – 消费者模式是许多众所周知的模式之一,它恰好解决了大部分并发编程问题。

阅读C#中的线程作者:Joseph Albahari 。 它是可用的最好和最经过审查的资源之一。

当我使用lock(C#)关键字时,这意味着我的类是否是线程安全的?

不! 没有可以使类线程安全的灵丹妙药。 lock关键字只是众多不同工具中的一种,可用于使类安全,以便multithreading同时访问。 但是,只使用lock不能保证任何东西。 正确使用同步机制使代码具有线程安全性。 有很多方法可以错误地使用这些机制。

如何评估一个类的线程安全性? 是否有任何测试可以确保一个类是100%线程安全的?

这是百万美元的问题! 测试multithreading代码非常困难。 Microsoft Research提供的CHESS工具是一种让并发程序员更轻松生活的尝试。

首先,不要使用锁(this)

这可能会导致死锁。 因为其他代码可以从类的范围之外锁定同一个对象。 您应该创建一个本地Object并将其用作类的锁。

其次,线程安全是一个复杂的问题。 网上有大量有关此内容的资料。

根据经验,所有公共方法都应该被锁定并且线程安全,以使类具有线程安全性。

如果一次只有一个线程可以修改从类创建的对象的状态,则类被认为是线程安全的,或者类提供了多个线程可以同时调用类的各种方法的function。

当我使用lock(C#)关键字时,这意味着我的类是否是线程安全的? 当您使用锁时,它意味着锁{}内的代码部分是线程安全的。 它不保证您的类是线程安全的。 正如Yochai Timmer所说lock(this)不是一个好主意

如何评估一个类的线程安全性? 是否有任何测试可以确保一个类是100%线程安全的? 我不确定是否有任何测试,因为在multithreading中总是可以获得正确的结果。 因此,为了确保您可以通过类的代码来查看它是如何确保它是线程安全的

非常简单的解释:线程安全类型意味着在使用类型时不需要任何其他同步机制。 假设您可以创建实例传递对另一个线程(或多个线程)的引用,并使用来自两个线程的方法/属性,而不会增加线程安全的额外开销。