为什么C#不允许锁定空值?

Cas*_*ash 39 c# multithreading locking

C#不允许锁定空值.我想在锁定之前我可以检查值是否为null,但是因为我没有锁定它,所以另一个线程可能会出现并使值为null!我怎样才能避免这种竞争条件?

Ana*_*tts 57

您无法锁定空值,因为CLR无法将SyncBlock附加到,这是允许CLR通过Monitor.Enter/Exit同步访问任意对象的内容(这是lock内部使用的)


Chr*_*ain 28

锁定永远不为null的值,例如

Object _lockOnMe = new Object();
Object _iMightBeNull;
public void DoSomeKungFu() {
    if (_iMightBeNull == null) {
        lock (_lockOnMe) {
            if (_iMightBeNull == null) {
                _iMightBeNull = ...  whatever ...;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

同时要小心避免这种有趣的竞争条件,双重检查锁定:双重检查锁定中的内存模型保证

  • 可能很高兴将readonly添加到锁定对象以调出所需的不变性 (6认同)

小智 5

这里有两个问题:

首先,不要锁定null对象.两个对象如何null区分,这没有意义?

其次,要在多线程环境中安全地初始化变量,请使用双重检查的锁定模式:

if (o == null) {
    lock (lockObj) {
        if (o == null) {
            o = new Object();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这将确保另一个线程尚未初始化该对象,并可用于实现Singleton模式.