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

时间:2011-07-13 08:08:55

标签: c# multithreading thread-safety

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

此类型是线程安全的。

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

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

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

  • 当我使用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;
}

感谢

6 个答案:

答案 0 :(得分:20)

  

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

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

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

阅读Threading in C# by Joseph Albahari。它是可用的最好和最经过审查的资源之一。

  

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

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

  

如何评估课程的线程安全性?有什么测试吗?   确保一个类是100%线程安全的吗?

这是百万美元的问题!测试多线程代码很难难以置信。 Microsoft Research提供的CHESS工具是一种让并发程序员更轻松生活的尝试。

答案 1 :(得分:11)

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

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

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

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

答案 2 :(得分:6)

首先,请勿使用锁定(此)

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

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

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

并不是一个好主意

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

答案 5 :(得分:1)

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