螺纹 - 安全辛格尔顿
本文关键字:安全 螺纹 | 更新日期: 2023-09-27 17:56:42
我有一个有 3 个静态成员的类。每个静态成员都不是线程安全的单一实例。我需要提供一个线程安全的实现供他们使用。可以吗?或者我需要为每个提供线程安全包装器?如果我应该 - 如何使用Lazy<T>
来做到这一点?
附加问题:SingeltonClass1/2/3
Measure()
和Do()
不是线程安全的func1()
线程安全的吗?
public class MyLazySingleton
{
// static holder for instance, need to use lambda to construct since constructor private
private static readonly Lazy<MyLazySingleton> _instance
= new Lazy<MyLazySingleton>(() => new MyLazySingleton());
// private to prevent direct instantiation.
private MyLazySingleton()
{
s_c1 = SingletonClass1.Instance();
s_c2 = SingletonClass2.Instance();
s_c3 = SingletonClass3.Instance();
}
// accessor for instance
public static MyLazySingletonInstance
{
get
{
return _instance.Value;
}
}
public void func1()
{
if (s_s1.Measure() || s_c2.Measure())
{
c_c3.Do();
}
}
static SingletonClass1 s_c1 = null;
static SingletonClass1 s_c2 = null;
static SingletonClass1 s_c3 = null;
}
如果它的构造函数应该有 2 个参数,我应该如何重新实现 MyLazySingleton? string str
和int i
我问了一个后续问题单例类中的线程安全方法
它是线程安全的。
Lazy<T>
的LazyThreadSafetyMode
的默认值为 ExecutionAndPublication
。
从 MSDN 页上的 new Lazy<T>(Func<T>)
构造函数:
可以使用使用此构造函数创建的实例 从多个线程并发。
初始化的惰性实例的线程安全模式 这个构造函数是LazyThreadSafetyMode.ExecutionAndPublication。
如果要使用另一个重载,在该重载中可以传递不同的LazyThreadSafetyMode
值,则不会是线程安全的。但是像现在这样使用构造函数,它是线程安全的。
:关于您的其他编辑问题,如果您的SingletonClass1
类型的这些方法不是线程安全的:那么不,func1
也不是线程安全的。
从 Lazy<T>
MSDN 页面:
使惰性对象线程安全并不能保护惰性对象线程 初始化的对象。如果多个线程可以懒惰地访问 初始化的对象,必须使其属性和方法安全 多线程访问。
您需要确保这些类之间的这些方法/交互是线程安全的。这可能就像用 lock
语句包装func1
体一样简单,但我不能确定取决于你的 3 个 SingletonClass1
实例如何相互交互或调用代码如何访问它们。
为了确保线程安全,您必须设置 Lazy<T>
构造函数的 LazyThreadSafetyMode
参数。有 3 个可用值:
-
None
:不是线程安全的 -
PublicationOnly
:可以创建许多MyLazySingleton
实例,但Value
属性只会发布/返回一个实例。在内部,它使用Interlocked.CompareExchange
-
ExecutionAndPublication
:该值仅创建一次
下面是一个示例:
new Lazy<Test>(() => new Test(), LazyThreadSafetyMode.ExecutionAndPublication)