Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about lock objects and sub classes

So, I have a base class which has a private locking object like so:

class A
{
    private object mLock = new object();

    public virtual void myMethod()
    {
        lock(mLock)
        {
            // CS
        }
    }
}

This locking object is used for most of A's operations... because they need to be thread safe.

Now, lets say I inherit from A like so:

class B : public A
{
    public override void myMethod()
    {
        lock(???)
        {
            // CS of mymethod here

            // Call base (thread safe alread)
            base.myMethod();
        }
    }
}

What is the convention for making B thread safe? Should B also have a private locking object like A does? What if I need to call the base method like above?

I guess I'm just curious what the convention is for making subclasses thread safe when the base class is already thread safe. Thanks!

Edit: Some are asking what I mean by "thread safe"... I'll clarify by adding that I'm trying to achieve thread safety through mutual exclusion... Only one thread at a time should be executing code which may alter the state of the object.

like image 595
Polaris878 Avatar asked Mar 20 '26 19:03

Polaris878


2 Answers

You would potentially expose the lock used by A:

protected object SyncLock { get { return mLock; } }

If B had its own lock object, you could easily end up with:

  • Different locks being used, potentially leading to race conditions. (It may be fine - if the operations occurring while holding lock B are orthogonal to those occurring while holding lock A, you may just get away with it.)
  • Locks being taken out recursively in different orders, leading to deadlocks. (Again, the orthogonality argument applies.)

As locks are recursive in .NET (for better or worse), if your override locks on the same object as A's implementation, it's fine to call base.myMethod and recursively acquire/release the lock.

Having said all of this, I'm keen on making most classes non-thread safe or immutable (only classes which are about threading need threading knowledge) and most classes don't need to be designed for inheritance IMO.

like image 142
Jon Skeet Avatar answered Mar 23 '26 08:03

Jon Skeet


It depends really. If your subclass is only using the safe methods from your base class and doesn't add any extra unsafe state, than you don't have to do anything (preferred). If it add some extra state which is not correlated with the state of the base class, then you can create a separate lock object in the subclass and use that. If, on the other hand, you need to make sure that the new state and the state from the base class are changed in some sort "transactional" way, then I would make the lock object in the base class protected and use that.

like image 41
Grzenio Avatar answered Mar 23 '26 08:03

Grzenio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!