C # thread lock (up)
This article starts with the class relationship diagram of monitor, mutex, manualresetevent, autoresetevent, and waithandler. I hope that through this introduction, I can have a general understanding of common thread synchronization methods, the application details of each method are not explained too much. Let's take a look at the relationships between these classes:
1. Lock keyword
Lock is the C # keyword. It marks the statement block as a critical section to ensure that when one thread is located in the critical section of the Code, the other thread does not enter the critical section. If other threads attempt to enter the locked code, it waits until the object is released. The method is to obtain the mutex lock of a given object, execute the statement, and then release the lock.
Msdn provides considerations for using lock. Generally, you should avoid locking the public type. Otherwise, the instance will be out of the control scope of the Code. Common structures such as lock (this), lock (typeof (mytype), and lock ("mylock") violate this rule.
1) if the instance can be accessed by the public, the lock (this) problem will occur.
2) If mytype can be publicly accessed, the lock (typeof (mytype) problem will occur. Because all instances of a class have only one type object (this object is the return result of typeof ), lock it to lock all instances of the object. At present, Microsoft does not recommend using lock (typeof (mytype) because locking type objects is a very slow process, other threads in the class, or even other programs running in the same application domain, can access this type of object. Therefore, they may be used to lock the type object instead of you, it completely blocks your execution and causes your own code to be suspended.
3) any other code using the same string in the process will share the same lock, so the lock ("mylock") problem occurs. This problem is related to the mechanism by which. NET Framework creates strings. If both string values are "mylock", the memory points to the same string object.
The best practice is to define private objects to lock, or private static object variables to protect the data shared by all instances.
Let's take a look at the essence of the lock keyword through il dasm. Below is a simple test code:
Lock (lockobject)
{
Int I = 5;
}
Use il dasm to open the compiled file. The above statement block generates the Il code:
Il_0045: Call void [mscorlib] system. Threading. Monitor: enter (object)
Il_004a: NOP
. Try
{
Il_004b: NOP
Il_004c: LDC. i4.5
Il_004d: stloc.1
Il_004e: NOP
Il_004f: Leave. s il_0059
} // End. Try
Finally
{
Il_0051: ldloc.3
Il_0052: Call void [mscorlib] system. Threading. Monitor: exit (object)
Il_0057: NOP
Il_0058: endfinally
} // End Handler
Through the above code, we can clearly see that the lock keyword is actually an encapsulation of the enter () and exit () Methods of the monitor class, and through try... catch... the finally statement block ensures that monitor is executed after the lock statement block ends. exit () method to release the mutex lock.
2. Monitor class
The monitor class grants an object lock to a single thread to control access to the object. Object locks provide the ability to restrict access to critical zones. When a thread has an object lock, no other thread can obtain the lock. You can also use monitor to ensure that no other thread is allowed to access the application code section being executed by the lock owner, unless another thread is using another lock object to execute the code.
Through the analysis of the lock keyword, we know that lock is an encapsulation of the enter and exit of monitor, and it is more concise to use. Therefore, the enter () and exit () of the monitor class () the combination of methods can be replaced by the lock keyword.
In addition, the monitor class has several common methods:
Tryenter () can effectively solve problems such as long-term crashes. If tryenter is used frequently in a concurrent and persistent environment, it can effectively prevent deadlocks or long waits. For example, you can set a waiting time bool gotlock = monitor. tryenter (myobject, 1000) so that the current thread can decide whether to continue the following operations based on the returned bool value after waiting for 1000 seconds.
Wait () releases the lock on the object to allow other threads to lock and access the object. When other threads access an object, the calling thread will wait. The pulse signal is used to notify the waiting thread of changes to the object state.
Pulse (), pulseall () sends signals to one or more waiting threads. This signal indicates that the status of the waiting thread lock object has changed, and the lock owner is ready to release the lock. Wait for the thread to be placed in the ready queue of the object so that it can finally receive the object lock. Once the thread has a lock, it can check the new State of the object to see if it has reached the desired state.
Note: The pulse, pulseall, and wait methods must be called from the synchronized code block.
Let's assume a situation: Mom makes a cake, and the child is a little embarrassed. Mom needs to eat every piece of cake she prepared. After the mother prepared a piece, she told the child that the cake was ready. The following example uses the wait and pulse methods of the monitor class to simulate a child's eating cake.
Example of wait and pulse
The purpose of this example is to understand how wait and pulse ensure thread synchronization, and pay attention to the differences between wait (obeject) and wait (object, INT) methods, the key to understanding the differences between them is to understand that the synchronization object contains several references, including references to the thread with the current lock and the ready queue (including the thread preparing to obtain the lock) and the reference to the waiting queue (including the threads waiting for the notification of object status changes.
ZZ from SOLDIER: http://www.cnblogs.com/dabing/archive/2009/04/20/1439506.html
-------------
How to read Visio?