A few days ago and colleagues heated discussion, a little harvest, recorded.
First, give the definition of MSDN:
The lock keyword can be used to ensure that a block of code finishes running without being interrupted by another thread. This is accomplished by acquiring a mutex for a given object while the code block is running.
Let's take a look at the execution process, and the code example is as follows:
If thread a executes first, thread B is slightly slower. Thread A executes to the lock statement to determine if obj has requested a mutex.
The basis for judgment is to object with an existing lock. ReferenceEquals comparison (not confirmed here), if not saved
In, a new mutex is applied, and thread a enters the lock.
This assumes that thread B is started, and thread A has not finished executing the code inside the lock. Thread B executes to the lock statement and checks to obj
A mutex has been requested and waits until thread A completes, releasing the mutex, and thread B can request a new mutex and execute
Lock inside the code.
Next, let's say some of the lock objects.
Why not lock value types, such as lock (1)? Lock essentially monitor.enter,monitor.enter the value type into boxing,
Each lock is a boxed object. Lock is actually a compiler-like syntax sugar, so the compiler directly restricts the type of lock value that cannot be locked.
10,000 step back, even if the compiler allows you to lock (1), but object. ReferenceEquals (1,1) always returns false because
Each boxing is a different object), that is, each time you will be judged not to request a mutex, so at the same time, other threads can still
Enough access to the code inside, not to achieve the effect of synchronization. Likewise lock (object 1) does not work.
What about the lock ("xxx") string? The exact words on MSDN are:
Locking a string is particularly dangerous because the string is "temporarily" reserved by the common language runtime (CLR). This means that any given string in the entire program
Has only one instance, that is, the same object represents the text in all threads of all running application domains. Therefore, as long as the application
A lock is placed on a string with the same content anywhere in the program process, and all instances of that string in the application are locked.
In general, it is best to avoid locking public types or locking object instances that are not controlled by the application. For example, if the instance can be publicly accessed,
The lock (this) may be problematic because uncontrolled code may also lock the object. This can lead to a deadlock, that is, two or more lines
Process waits to release the same object. For the same reason, locking a common data type (compared to an object) can also cause problems. and lock (This)
is valid only for the current object, if the effect of synchronization is not reached between multiple objects.
Lock (typeof (Class)) is as wide as a locked string.
Some system classes provide members that are dedicated to locking. For example, the Array type provides SyncRoot. Many collection types also provide SyncRoot.
Custom classes recommend private read-only static objects, such as:
private static readonly Object obj = new Object ();
Why do you want to set it as read-only? Because if you change the value of obj in the lock snippet, the other threads are free, because the mutex
Objects changed, object. ReferenceEquals must return FALSE.