I’m trying to learn threading in C#, and I’ve seen something crop up in few articles but I am not sure I fully understand it: In the given two examples, what would the fundamental difference between getting a lock on ‘this’ vs ‘thisLock’.
Example 1:
class Account
{
decimal balance;
private Object thisLock = new Object();
public void Withdraw(decimal amount)
{
lock (thisLock)
{
if (amount > balance)
{
throw new Exception("Insufficient funds");
}
balance -= amount;
}
}
}
Example 2:
class Account
{
decimal balance;
public void Withdraw(decimal amount)
{
lock (this)
{
if (amount > balance)
{
throw new Exception("Insufficient funds");
}
balance -= amount;
}
}
}
From my understanding, I would of thought that ‘thisLock’ only stops other threads from entering that specific area of code.
Were as getting a lock on ‘this’ would stop all operations on the object, i.e. calls to other methods by other threads?
Have I fundamentally miss understood this, or is that the correct conclusion?
The difference is locking granularity.
When locking an object, (simplified) a bit is set on the instance. Anyone else trying to lock the same instance will end up in a wait state until the lock is released by the other.
In many cases, methods on a object can be used at the same time (i.o.w. In parallel). Locking the entire object (this) would exclude the usage of any other method if that method also uses '
lock(this)'.Since lock can be used on any reference type, we can create "lock" objects. Where we implement the '
lock(lockObject)' on a exclusion basis.As example;
MethodB1 and MethodB2 cannot be used at the same time
MethodA1/2 can be used at the same time as MethodB1/2.
If we would use the
lock(this)on every method, we would also be exluding MethodA1/2 from running at the same time as MethodB1/2.By creating 2 lock objects (lockAMethods, lockBMethods) we can now implement our locking more granular.
lock(lockAMethods)" to make sure the A1 and A2 methods cannot run at the same time."lock(lockBMethods)" to make sure the B1 and B2 methods cannot run at the same time.We can however
lock(lockAMethods)andlock(lockBMethods)at the same time. Hence we can now run MethodA1/2 at the same time as MethodB1/2.Hope this helps,