2016-05-05 52 views
1

我可能会在某处丢失一些非常明显的文档,但它是静态只读成员变量,保证能够正确初始化以用作锁对象?C#锁对象是否需要延迟初始化

简而言之,我有一个库类,它对外部资源执行操作,该资源应该只有一个实例在任何时候触及它(不必担心另一个进程,它只是在一个进程中) 。库类本身可以在多个线程中拥有多个实例,因此为了确保一次只有一个实例访问所述资源,我需要使用一个锁。

我见过很多像这样的锁对象声明。

private static readonly object _lockObj = new object();

可以这样保证多个线程不会,坏时机,同时初始化两个对象和两个对象锁定?或者我应该像这样创建锁定对象。

private static readonly Lazy<object> _lockObj = new Lazy<object>(() => new object());

附:我指的是锁定关键字C#的lock(_lockObj){...}

+0

锁定可以在任何物体上完成。如果你的说法是真的,那么“静态只读”字段可能会有多个值,而这些值并不是预期的。只要他们访问同一个班级,你应该很好。警惕通用类tho;) –

+1

CLR保证每个appdomain会初始化一次类型。静态字段初始值设定项在类型初始值设定项内运行,并在类型的静态构造函数的主体之前运行(如果有的话)。因此,假设两个线程在同一个appdomain中激活一个方法,那么就不可能有一个获得不同锁定对象的竞赛。 –

+0

如果没有这样的工作,那么我不明白你的解决方案将如何帮助。您只需将风险转移到两个'Lazy'实例,然后初始化两个不同的对象。 –

回答

2

运行时保证只有一个静态成员字段的副本。你甚至可以在没有任何课程的情况下使用它。用作锁对象是安全的。

+0

所以,即使对象有点复杂,比如信号量,我也可以做到这一点。 '公共静态只读SemaphoreSlim _semaphore =新SemaphoreSlim(3)'不使用Lazy <>初始化? – ShuberFu

+0

是的,_semaphore是在它可以使用之前构造的。 –

+0

我不认为你需要一直使用懒惰。这不像你的应用程序是资源关键的应用程序。 –