使用私有静态只读对象来锁定多线程是很常见的。 我理解私有通过收紧封装来减少锁定对象的入口点,从而获得最重要的访问点。
但为什么要静止?
private static readonly object Locker = new object();
最后,该字段仅在我的班级中使用,我也可以使用它:
private readonly object Locker = new object();
有任何意见吗?
更新
作为一个例子,我粘贴了这段代码(只是一个例子)。我可以使用静态或非静态锁定器,两者都可以正常工作。考虑到下面的答案,我应该更喜欢这样定义我的储物柜? (对不起,我下周接受采访,需要了解每一个细节:)
private readonly object Locker = new object();
以下是代码:
private int _priceA;
private int _priceB;
private EventWaitHandle[] _waithandle;
private readonly IService _service;
//ctor
public ModuleAViewModel(IService service)
{
_service = service;
_modelA = new ModelA();
_waithandle = new ManualResetEvent[2];
_waithandle[0] = new ManualResetEvent(false);
_waithandle[1] = new ManualResetEvent(false);
LoadDataByThread();
}
private void LoadDataByThread()
{
new Thread(() =>
{
new Thread(() =>
{
lock (Locker)
{
_priceA = _service.GetPriceA();
}
_waithandle[0].Set();
}).Start();
new Thread(() =>
{
lock (Locker)
{
_priceB = _service.GetPriceB();
}
_waithandle[1].Set();
}).Start();
WaitHandle.WaitAll(_waithandle);
PriceA = _priceA;
PriceB = _priceB;
}).Start();
}
由于
答案 0 :(得分:165)
使用私有静态只读对象锁定多线程并不“非常常见” - 相反,通常以适当/选择的粒度使用锁 。有时候是static
。更常见的是,IMO,它不是 - 而是基于实例。
您看到static
锁的主要时间是全局缓存,或者是全局数据/单例的延迟加载。在后者中,有更好的方法无论如何。
所以它真的取决于:你的场景中如何使用Locker
?它是否保护本身静态的东西?如果是这样,锁应该是静态的。如果它正在保护基于 instance 的内容,那么IMO锁定也是基于实例的。
答案 1 :(得分:77)
它不一定是静态的,事实上有时它应该不是静态的。
变量应与您用于锁定的方法位于相同的范围内。如果方法是静态的,则变量应该是静态的,如果方法是实例方法,则变量应该是实例变量。
当用于锁定实例方法时,静态变量仍然有效,但是你将锁定太多。您将锁定所有实例中的所有方法,而不仅仅是同一实例中的方法。
答案 2 :(得分:27)
锁的范围和生命周期可以/应该取决于您要锁定的“事物”。 静态锁主要用于锁定静态内容。