Why does the lock object have to be static?

C#MultithreadingLocking

C# Problem Overview


It is very common to use a private static readonly object for locking in multi threading. I understand that private reduces the entry points to the locking object by tightening the encapsulation and therefore access to the most essential.

But why static?

private static readonly object Locker = new object();

At the end the field is only used within my class only, and I could also just use this instead:

private readonly object Locker = new object();

Any comments?

UPDATE:

As an example I have pasted this code (just an example). I could use static or non-static locker on this and both would work fine. Considering the answer below I should be rather defining my locker like this?

private readonly object Locker = new object();

And here is the code:

    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();
        }

Thanks

C# Solutions


Solution 1 - C#

It isn't "very common to use a private static readonly object for locking in multi threading" - rather, it is common to use a lock at the appropriate / chosen granularity. Sometimes that is static. More often, IMO, it isn't - but is instance based.

The main time you see a static lock is for a global cache, or for deferred loading of global data / singletons. And in the latter, there are better ways of doing it anyway.

So it really depends: how is Locker used in your scenario? Is it protecting something that is itself static? If so, the lock should be static. If it is protecting something that is instance based, then IMO the lock should also be instance based.

Solution 2 - C#

It doesn't have to be static, in fact sometimes it should not be static.

The variable should live in the same scope as the methods where you use it for locking. If the methods are static, the variable should be static, and if the methods are instance methods, the variable should be an instance varible.

A static variable will still work when used to lock in an instance method, but then you will be locking too much. You will lock all methods in all instances, not just the methods in the same instance.

Solution 3 - C#

The scope and lifetime of a lock can/should depend on the 'thing' you want to lock. Static locks are mostly used to lock static things.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHoumanView Question on Stackoverflow
Solution 1 - C#Marc GravellView Answer on Stackoverflow
Solution 2 - C#GuffaView Answer on Stackoverflow
Solution 3 - C#EmondView Answer on Stackoverflow