我有一个有3个静态成员的类。每个静态成员都不是线程安全的单例。
我需要提供一个线程安全的实现供它们使用。没关系吗?或者我需要为每个实现提供线程安全的包装?如果我应该 - 我怎样才能使用Lazy<T>
?
其他问题:Measure()
Do()
和SingeltonClass1/2/3
的{{1}}不是线程安全的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
答案 0 :(得分:1)
它是线程安全的。
Lazy<T>
LazyThreadSafetyMode
的默认值为ExecutionAndPublication
。
来自new Lazy<T>(Func<T>)
constructor上的MSDN页面:
可以使用使用此构造函数创建的实例 同时来自多个线程。
使用初始化的Lazy实例的线程安全模式 这个构造函数是LazyThreadSafetyMode.ExecutionAndPublication。
如果您使用another overload可以传递不同的 LazyThreadSafetyMode
值,那么它就不是线程安全的。但是现在使用构造函数,它是线程安全的。
编辑:关于您的其他已编辑问题,如果SingletonClass1
类型上的那些方法不线程安全:那么否,func1
是也不是线程安全的。
使Lazy对象线程安全无法保护懒惰 初始化对象。如果多个线程可以访问懒惰 初始化对象,您必须使其属性和方法安全 多线程访问。
您需要确保这些类之间的那些方法/交互是线程安全的。这个可能就像使用func1
语句包装lock
正文一样简单,但我不能肯定地说明取决于SingletonClass1
的3个实例的方式互相交流或调用代码如何访问它们。
答案 1 :(得分:0)
要确保线程安全,您必须设置LazyThreadSafetyMode
构造函数的Lazy<T>
参数。有3个可用值:
None
:不是线程安全的PublicationOnly
:可能会创建许多MyLazySingleton
个实例,但Value
属性只会发布/返回一个实例。在内部,它使用Interlocked.CompareExchange
ExecutionAndPublication
:值只创建一次以下是一个例子:
new Lazy<Test>(() => new Test(), LazyThreadSafetyMode.ExecutionAndPublication)