8

Can someone clarify me:

The statements inside the lock will be locked no one can go through unless it's finished and release the lock. Then what is the object inside the lock used for?

lock (obj) 
{ 
    //statement 
}

Does that mean the obj is being locked and cannot be used from anywhere else unless the lock has done his work?

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
LittleFunny
  • 8,155
  • 15
  • 87
  • 198
  • 2
    You don't care about the object being locked...it's only there to allow the lock to do its job. You care about what is going on ***inside*** the lock. – David L Jun 15 '16 at 04:52
  • 4
    It's simply used as a key to provide an identity to the locked region of code. You can use the same object elsewhere to allow different blocks of code to be mutually locked. – Enigmativity Jun 15 '16 at 04:54
  • 1
    Also you're slightly wrong with "no one can go through unless it's finished" - the current thread can re-enter the lock - it's only other threads that get locked out. – Enigmativity Jun 15 '16 at 04:55
  • 1
    it's just a representation of a lock. locking that object signifies that there is a thread in control for the function within.. – jegtugado Jun 15 '16 at 05:04
  • 1
    Think of the object that you pass to the lock statement as the key, a key that remains in the lock until the thread that put the key in the lock leaves the scope – Emond Jun 15 '16 at 05:07
  • Based on accepted question should be duplicate of http://stackoverflow.com/questions/6029804/how-does-lock-work-exactly (I've re-opened question based on incorrect assumption that Simon is interested in whether `obj` have any special meaning/restrictions on it which turned out not the case) – Alexei Levenkov Jun 15 '16 at 05:23

2 Answers2

13

I've made a very simple class to illustrate what the object in the lock is there for.

public class Account
{
    private decimal _balance = 0m;
    private object _transactionLock = new object();
    private object _saveLock = new object();

    public void Deposit(decimal amount)
    {
        lock (_transactionLock)
        {
            _balance += amount;
        }
    }

    public void Withdraw(decimal amount)
    {
        lock (_transactionLock)
        {
            _balance -= amount;
        }
    }

    public void Save()
    {
        lock (_saveLock)
        {
            File.WriteAllText(@"C:\Balance.txt", _balance.ToString());
        }
    }
}

You'll notice that I have three locks, but only two variables.

The lines lock (_transactionLock) mutually lock the regions of code to only allow the current thread to enter - and this could mean that the current thread can re-enter the locked region. Other threads are blocked no matter which of the lock (_transactionLock) they hit if a thread already has the lock.

The second lock, lock (_saveLock), is there to show you that the object in the lock statement is there to identify the lock. So, if a thread were in one of the lock (_transactionLock) statements then there is nothing stopping a thread to enter the lock (_saveLock) block (unless another thread were already there).

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
-2

Read up on semaphores and monitors. When it comes to multi-threading, you want to protect the Critical Section of the code, so that the object in question is not being accessed while an operation is being performed on it. The critical section is what's being enclosed inside the lock.

This is all done to avoid dead locks and live locks. Once again, you only need the lock if your application is multi-threaded.

Mutex
  • 72
  • 4