gpt4 book ai didi

c# - 使用 setter 时,何时应该在多线程单例中锁定静态实例?

转载 作者:太空宇宙 更新时间:2023-11-03 20:50:55 25 4
gpt4 key购买 nike

试图了解何时锁定静态变量被认为是最佳实践。静态实例 setter 是线程安全的吗?如果不是,应该是,为什么(不使其成为线程安全的后果是什么)?

class MyClass
{
private static MyClass _instance;

private static readonly object _padlock = new object();

public static MyClass Instance
{
get
{
if(_instance == null)
{
lock(_padlock)
{
if(_instance == null)
{
_instance = new MyClass();
}
}
}
return _instance;
}
set => _instance = value;
}

}

最佳答案

这称为双重检查锁定

但是,双重检查锁定要求底层字段是volatile1

简而言之,分配是原子的,但它需要在不同的核心/CPU 之间同步(完全隔离,通过锁)。原因是另一个核心同时读取该值可能会缓存一个过时的值1

有几种方法可以使代码线程安全:

  • 避免双重检查锁定,并简单地执行lock 语句中的所有操作。
  • 使用 volatile 关键字使字段volatile
  • 使用 Lazy 类,保证线程安全

注意:完全无人看守的二传手进一步增加了复杂性3..

但是,在您的情况下,使用双重检查锁定 可能会在使用 volatile 字段进行一次检查和锁定时正常工作,但我认为您最好的选择是完全锁定一切并保证安全

public static MyClass Instance
{
get
{
lock(_padlock)
{
if(_instance == null)
_instance = new MyClass();
return _instance;
}

}
set
{
lock(_padlock)
{
_instance = value;
}
}
}

注意:是的,它会导致性能下降


引用


其他资源

关于c# - 使用 setter 时,何时应该在多线程单例中锁定静态实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55368906/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com