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

10 c# asp.net

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

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

Nei*_*ell 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果类型应用了如果多个线程同时访问共享数据则不会发生损坏的原则,则该类型被视为"线程安全".

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


Ode*_*ded 7

线程安全代码意味着可以使用许多线程访问并仍能正常运行的代码.

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

使用非线程安全类型需要您自己管理同步.


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