5

This is something I've never understood. It almost seems like a hack to create a dummy object that gets locked, like the example

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

from https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx.

Why couldn't the language designers make it so that

class Account { decimal balance; public void Withdraw(decimal amount) { lock { if (amount > balance) { throw new Exception("Insufficient funds"); } balance -= amount; } } } 

would be equivalent?

2
  • 5
    @Sayse Not at all, otherwise nobody would understand how to use lock in the first place. The reasons why need the lock statement needs to be passed a parameter are pretty clear, and the question is very valid if the author doesn't understand those reasons. Commented Nov 5, 2016 at 23:15
  • @rucamzu - I think I misread the question Commented Nov 6, 2016 at 8:22

2 Answers 2

7

The instance passed to lock serves to identify the critical section.

You may have any number of unrelated critical sections in your code, and each one will be locking a different object. A parameterless lock statement the likes of the one you suggest wouldn't be able to distinguish between many critical sections.

EDIT

Although it might seem obvious, it's worth noting that every single part needing to enter a given critical section must have access to the locked object. So it's not a matter of creating an arbitrary instance just before and in the same scope than the lock statement.

Sign up to request clarification or add additional context in comments.

2 Comments

Yes you are right, I misread it and I think that he doesn't understand what is lock doing. Thanks for the comment
@mybirthname No problem at all. And just for the record, I found your explanation clear and useful.
1

I think the confusion lies in what the lock keyword is doing. It is not saying only 1 thread can enter that section of code but it is saying 2 things:

  1. only one thread can enter this section of code who has thisLock
  2. Any other section which is locked with thisLock is also not to be allowed entry by any thread except this thread since this thread has thisLock.

What you are suggesting would only be doing the 1st one but not both. Look at this example:

class Account { decimal balance; private Object thisLock = new Object(); private Object thisLock2 = new Object(); public void Withdraw(decimal amount) { lock (thisLock) { if (amount > balance) { throw new Exception("Insufficient funds"); } balance -= amount; } // more code here but no locking necessary... lock(thisLock) { // only one thread can enter here who has thisLock } lock (thisLock2) { // If T1 (thread1) is working with thisLock, T2 can come here since it has nothing to do // with thisLock. } } public void AnotherOperation() { lock (thisLock) { // code here... } } public void YetAnotherOperation() { lock (thisLock) { // code here... } } } 

When a thread, say T1, is doing the withdrawal part with the first lock, all other sections of the class with lock(thisLock) are not allowed entry by any other thread as well. However, the part with thisLock2 is allowed to be entered by other threads.

The best way to think of the lock keyword, at least it helped me when I was learning was to think of it as a hostage. In other words, when certain parts of the code are being executed it needs to take a hostage (thisLock) in your example. So once that thisLock is taken as hostage, no other thread can take it as hostage until that thread releases the hostage. Therefore, all other sections of code which also need the same hostage, become unavailable.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.