什么是“线程安全类型”?我们什么时候需要使用“锁定”声明?

时间:2010-11-01 14:42:18

标签: c# asp.net

我阅读了有关线程安全类型和“锁定”语句的所有文档,但我仍然没有100%获得它。

我到底什么时候需要使用“锁定”声明?它与(非)线程安全类型的关系如何?谢谢。

3 个答案:

答案 0 :(得分:12)

想象一下一个带有全局变量的类的实例。想象一下,两个线程在该对象上完全同时调用的方法,并且该方法更新了内部的全局变量。

可能是变量中的值会被破坏。不同的语言和编译器/解释器将以不同的方式处理(或根本不处理......),但关键是你会得到“不受欢迎的”和“不可预测的”结果。

现在假设该方法在尝试读取或写入变量之前获取变量的“锁定”。调用该方法的第一个线程将获得对该变量的“锁定”,调用该方法的第二个线程将必须等到第一个线程释放锁定。虽然你仍然有竞争条件(即第二个线程可能会覆盖第一个线程的值),但至少你有可预测的结果,因为没有两个线程(彼此不知道)可以同时修改该值。

使用lock语句获取变量的锁定。通常,您将定义一个单独的对象变量,并将其用于锁定对象:

public class MyThreadSafeClass
{
    private readonly object lockObject = new object();
    private string mySharedString;

    public void ThreadSafeMethod(string newValue)
    {
        lock (lockObject)
        {
            // Once one thread has got inside this lock statement, any others will have to wait outside for their turn...
            mySharedString = newValue;
        }
    }
}

如果类型适用于如果多个线程同时访问共享数据则不会发生损坏的原则,则该类型被视为“线程安全”。

注意“不可变”和“线程安全”之间的区别。 Thread-safe表示你已经为场景编码,并且如果两个线程同时访问共享状态,则不会损坏,而不变性只是说你返回一个新对象而不是修改它。不可变对象是线程安全的,但并非所有线程安全对象都是不可变的。

答案 1 :(得分:7)

线程安全代码是指可以通过多个线程访问并仍能正常运行的代码。

在C#中,这通常需要某种同步机制。一个简单的例子是lock语句(在Monitor.Enter之后的幕后)。由lock块包围的代码块一次只能由一个线程访问。

任何非线程安全类型的使用都要求您自己管理同步。


在C#中学习线程的一个很好的资源是Joe Albahari的免费电子书,here

答案 2 :(得分:0)