关于c#:为什么锁对象必须是静态的?

Why does the lock object have to be static?

在多线程中使用私有静态只读对象锁定是非常常见的。我理解private通过收紧封装来减少锁定对象的入口点,因此访问最基本的。

但为什么是静态的呢?

1
private static readonly object Locker = new object();

最后,该字段只在我的类中使用,我也可以使用它来代替:

1
private readonly object Locker = new object();

有什么意见吗?

更新:

作为一个例子,我粘贴了这段代码(只是一个例子)。我可以使用静态或非静态的储物柜,两者都可以工作。考虑到下面的答案,我应该这样定义我的储物柜?(对不起,我下周有个面试,需要知道每一个细节。)

1
private readonly object Locker = new object();

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
    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();
        }

谢谢


在多线程中使用私有静态只读对象进行锁定"并不常见",相反,在适当/选定的粒度上使用锁是常见的。有时这就是static。更常见的是,在我看来,它不是——而是基于实例的。

您看到static锁的主要时间是用于全局缓存,或用于延迟加载全局数据/单例。在后一种情况下,有更好的方法可以做到这一点。

所以这真的取决于:在您的场景中,Locker是如何使用的?它是在保护本身是静态的东西吗?如果是这样,锁应该是静态的。如果它保护的是基于实例的东西,那么IMO锁也应该是基于实例的。


它不一定是静态的,事实上有时它不应该是静态的。

变量应与用于锁定的方法位于同一范围内。如果方法是静态的,那么变量应该是静态的;如果方法是实例方法,那么变量应该是实例变量。

静态变量在用于锁定实例方法时仍然可以工作,但这样会导致锁定过多。您将锁定所有实例中的所有方法,而不仅仅是同一实例中的方法。


锁的作用域和生存期可以/应该取决于您想要锁定的"东西"。静态锁主要用于锁定静态对象。