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,