This article describes the usage of lock in C#. Share it for your reference. The specific analysis is as follows:
The lock keyword can be used to ensure that the code block is completed without being interrupted by other threads. This is done by acquiring a mutex for a given object during a code block run.
Let’s take a look at the execution process first, the code example is as follows:
The lock statement is used to acquire a mutex for a given object, execute a statement, and then release the lock.
lock-statement:(lock statement:)
The expression of the lock statement must represent a value of a reference type. Implicit boxing is never performed for expressions in lock statements, so if the expression represents a value of a value type, it will result in a compile-time error.
The following lock statement:
(where x is an expression of reference type) is completely equivalent to
try {
...
}
finally {
(x);
}
The difference is: x is only calculated once in actual execution.
When a mutex has been occupied, the code executed in the same thread can still acquire and release the lock. However, code executed in other threads cannot obtain the lock until it is released.
An object of a class can be conveniently used as a mutex for static methods of the class. For example:
{
public static void add(object x) {
lock (typeof(cache)) {
...
}
}
public static void remove(object x) {
lock (typeof(cache)) {
...
}
}
}
Suppose thread a executes first, thread b is a little slower. Thread a executes the lock statement to determine whether obj has applied for a mutex. The basis for judgment is to compare with the existing lock one by one (not confirmed here). If it does not exist, a new mutex lock is applied. At this time, thread a enters the lock.
At this time, assume that thread b is started, and thread a has not yet executed the code in lock. Thread b executes the lock statement and checks that obj has applied for a mutex, so it waits; until thread a completes execution and releases the mutex, thread b can only apply for a new mutex and executes the code inside the lock.
Next, let’s talk about some of the objects to lock.
Why can't the value type be locked, such as lock(1)? In essence, lock will make the value type box, and each time the lock is the boxed object. lock is actually a syntactic sugar similar to the compiler, so the compiler directly restricts the type of lock value.
To take a step back, even if the compiler allows you to lock(1), (1,1) always returns false (because there are different objects after packing), that is, it will be judged that the mutex is not applied for every time. In this way, other threads can still access the code inside at the same time, and cannot achieve the synchronization effect. Similarly, lock((object)1) is not OK.
So what about the lock("xxx") string? The original words on msdn are:
Locking strings is especially dangerous because strings are "standby" by the common language runtime (clr). This means that any given string in the entire program has only one instance, that is, this same object represents the text in all threads of all running application domains. Therefore, as long as a lock is placed on a string with the same content at any location in the application process, all instances of that string in the application will be locked.
In general, it is best to avoid locking public types or locking instances of objects that are not controlled by the application. For example, if the instance can be publicly accessed, lock(this) may have problems, because uncontrolled code may also lock the object. This can cause deadlocks, i.e. two or more threads waiting to release the same object. For the same reason, locking the public data type (compared to objects) can also cause problems. Moreover, lock(this) is only valid for the current object, and if multiple objects are not synchronized, the effect is not achieved.
lock(typeof(class)) is the same as lock strings, and the scope is too wide.
Some system classes provide members specifically for locking. For example, the array type provides syncroot. Many collection types also provide syncroot.
Custom classes recommend using private read-only static objects, such as:
Why set it to read-only? At this time, if the value of obj is changed in the lock code segment, other threads will be unblocked because of the mutex.
If the object changes, it will inevitably return false.
I hope this article will be helpful to everyone's C# programming.