为什么锁定对象必须是静态的?

Hou*_*man 105 c# multithreading locking

使用私有静态只读对象来锁定多线程是很常见的.我知道私有通过收紧封装来减少锁定对象的入口点,因此可以访问最重要的内容.

但为什么静止?

private static readonly object Locker = new object();
Run Code Online (Sandbox Code Playgroud)

最后,该字段仅在我的班级中使用,我也可以使用它:

private readonly object Locker = new object();
Run Code Online (Sandbox Code Playgroud)

任何意见?

更新:

作为一个例子,我粘贴了这段代码(只是一个例子).我可以使用静态或非静态锁定器,两者都可以正常工作.考虑到下面的答案,我应该更喜欢这样定义我的储物柜?(对不起,我下周接受采访,需要知道每一个细节:)

private readonly object Locker = new object();
Run Code Online (Sandbox Code Playgroud)

以下是代码:

    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();
        }
Run Code Online (Sandbox Code Playgroud)

谢谢

Mar*_*ell 169

使用私有静态只读对象来锁定多线程并不"非常常见" - 相反,通常以适当/选择的粒度使用锁.有时就是这样static.更常见的是,IMO,它不是 - 但是基于实例.

您看到static锁定的主要时间是全局缓存,或者是全局数据/单例的延迟加载.而在后者中,无论如何都有更好的方法.

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

  • 您能否提供更详细的延迟加载全球数据的更好方法? (23认同)
  • 我总是使用静态/易失性,因为如果有几个地方它是基于实例的,我仍然希望控制以线程安全的方式访问我的方法/变量。许多实例可能正在访问相同的资源,我想控制它。我也希望看到这样做更好。你有一个很好的代表,我相信你的回复也同样适合我采纳。请回复? (2认同)

Guf*_*ffa 81

它不必是静态的,其实有时它应该不会是一成不变的.

变量应与您用于锁定的方法位于相同的范围内.如果方法是静态的,则变量应该是静态的,如果方法是实例方法,则变量应该是实例变量.

当用于锁定实例方法时,静态变量仍然有效,但是您将锁定太多.您将锁定所有实例中的所有方法,而不仅仅是同一实例中的方法.

  • "a-ha"的+1 ...*您将锁定所有实例中的所有方法,而不仅仅是同一实例中的方法.* (26认同)
  • @radarbob - 次要细节:你不会_lock所有方法_你只需要锁定更多客户可能感兴趣的方法.方法永远不会被锁定,只是互斥锁已被占用. (3认同)
  • 我怀疑这个答案的措辞可能会产生误导 - 锁定不应该对方法的范围做任何事情 - 它应该只关心在这些方法中访问的*共享数据*的范围。实例方法可能不会访问任何共享数据(因此不需要锁定),可以访问静态共享数据(因此需要静态锁,重构也可能是个好主意),对于静态也是如此... (2认同)

Ern*_*rno 27

锁的范围和生命周期可以/应该取决于您想要锁定的"事物".静态锁主要用于锁定静态内容.

  • @Guffa这很奇怪,在你上面的评论中你正确地说:"你只是过于复杂的事情,"现在我看到1分钟才说,这似乎是你过于复杂的事情:) (12认同)
  • 次要细节:锁不是静态的,用于标识锁的对象是静态的.另一个小细节:你没有锁定"东西". (3认同)
  • 是的,我认为如果我们试图锁定错误的"事物",它们可能太大而且强大,有一天会逃脱. (2认同)