ReSharper 2025.2 Help

代码检查:可能错误实现了 Double-Check Locking 模式。 对已检查字段的读取访问。

请考虑以下代码片段:

public class Foo { private static volatile Foo _instance; private static readonly object Padlock = new object(); public static Foo GetValue() { if (_instance != null) return _instance; lock (Padlock) { if (_instance != null) return _instance; _instance = new Foo(); _instance.Init(); } return _instance; } private void Init() { // object initialization } }

如果我们假设 Init() 是用于初始化 Foo 状态的方法,那么上述代码在多线程环境中可能无法按预期运行。

可能会出现一种情况,一个线程执行了 _instance = new Foo(); 但尚未执行 _instance.Init();。 如果此时某个其他线程调用 GetValue() ,该方法会发现 _instance 不为 null,并将一个未初始化的实例返回给调用者。

对于上述代码,有两种方法可以解决此问题。

第一种,也是最明显的方法,是将 Init() 的内容移到一个私有构造函数中。

第二种方法是在一个未检查的变量中执行初始化,然后将其分配给已检查的变量,从而消除问题。 通过这种方式, _instance 只有在已经初始化后才会变为不为 null。 上述示例中 lock 语句中的代码可以重写为:

if (_instance != null) return _instance; var temp = new Foo(); temp.Init(); _instance = temp;

StackOverflow 上的这个回答解释了此模式的其他可能问题,以及为什么 _instance 应该声明为 volatile

最后修改日期: 2025年 9月 27日