How does the C#lock work?

Asked

Viewed 10,939 times

22

I was just looking at an article by MSDN, but it was not clear why to use this.

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

3 answers

39


Lock is a very useful tool when you need to ensure exclusive access to a given resource, or ensure Thread Safety.

This function makes use of an object as a synchronization flag (in your example, the object thislock).

In the example code, the first thread to execute the method Withdraw will get the lock of the object thislock, and will execute the code block. Any other thread that tries to execute the same instance of the method will enter Waitstate (or waiting state) if they find the instruction lock and another thread has the right of access.

A queue is created, and the threads on hold will receive the release of lock in FIFO style (First In, First Out).

16

To complement, the lock It’s a kind of traffic light. In fact through it it is possible to deploy a data structure capable of controlling the processing traffic that is called traffic light.

The lock turns on a red light telling any code that tries to access that chunk of memory it’s forbidden to do until the light goes out. Note that although it looks like a traffic light, it is not in fact. That’s why lock in itself can be used at a traffic light which is a somewhat more sophisticated structure.

It indicates for the entire application that at that time something will be done with the object that cannot be stopped. That no part of the application can consider the state of the object until it is released because the operation at that time may be inconsistent or incomplete.

When your code is compiled statement lock becomes a code equivalent to this:

bool lockWasTaken = false;
var temp = thisLock;
try {
    Monitor.Enter(temp, ref lockWasTaken);
    if (amount > balance) {
        throw new Exception("Insufficient funds");
    }
    balance -= amount;
} finally {
    if (lockWasTaken) {
        Monitor.Exit(temp); 
    }
}

I put in the Github for future reference.

Note that it is possible to get the same result using only the library but not recommended.

In codes you’re sure you’ll never have threads you do not need and should not use this type of synchronism. For some operations the performance cost of executing class methods Monitor may be prohibitive.

See the Reference Source of . NET to understand the inner workings of the class (not that it helps much :D).

  • 2

    +1, excellent mention to the semaphore structure.

5

It’s worth researching about resource competition. The semaphore for example can be used when you have a resource pool (for example 3 active connections) and need to ensure that none is used by more than one consumer.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.