How does C # lock work?

17

I was checking out an MSDN article, but it was not clear why 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;
        }
    }
}
    
asked by anonymous 12.08.2014 / 17:41

4 answers

27

Lock is a very useful tool when you need to grant exclusive access to a given feature, or ensure Thread safety .

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

In the sample code, the first thread executing the Withdraw method will get the lock of the thislock object, and will execute the code block. Any other thread attempting to execute the same instance of the method will enter WaitState (or waiting state ) if they find the lock statement and another in> have the right of access.

A queue is created, and threads on hold will receive FIFO-style lock release.

    
12.08.2014 / 17:47
11

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

The lock turns on a red light telling any code that tries to access that stretch of memory that it is prohibited to do until the light goes out. Note that although it looks like a traffic light, it is not. This is why lock itself can be used on a semaphore which is a slightly more sophisticated structure.

It indicates to the entire application that at that time something will be done with the object that can not be interrupted. 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 the 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 placed GitHub for future reference .

Note that you can achieve the same result using only the library but it is not recommended.

In codes that you are sure will never have threads you do not need and should not use this type of timing. For some operations the performance cost of running the methods of the class Monitor may be prohibitive.

See the Reference Source to understand the inner workings of the class (not that help a lot).

    
08.12.2014 / 21:18
4

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.

    
12.08.2014 / 22:43
-13

The lock keyword marks a blocking of statements as a critical section, getting the muting exclusion block for a given object, executing a statement, and then releasing the lock. The following example includes a lock declaration.

The lock keyword ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, to lock, until the object is released. The section discusses Threading (C # and Visual Basic) targeting. The lock keyword calls Enter at the beginning of the block and Exit at the end of the block. ThreadInterruptedException is thrown if interrupt interrupts thread that is waiting to insert a lock statement. In general, avoid blocking on a type of public, or instances besides controlling your code. A common construct lock (this), lock (typeof (MyType)), and lock ("myLock") violates this guideline: lock (this) is a problem if the instance can be accessed publicly. lock (typeof (MyType)) is a problem if MyType is publicly accessible. lock ("myLock") is a problem since any other code in the process using the same string, share the same lock. The best practice is to set a private object to lock, or a private static object variable to protect data that is common to all instances. You can not use the wait keyword in the body of a lock statement.

    
12.08.2014 / 22:18