In this aspect, thread synchronization is rarely used. Every multi-thread-related problem must be reviewed. Today, when we look at asynchronous TCP, we repeat it.
There are two types of multi-thread synchronization: one is the semaphore, and the other is the mutex, exclusive
1.Semaphores:
The instance code is as follows:
Class Program
{Private int N1, N2, N3; eventwaithandle myeventwaithandle = new eventwaithandle (false, eventresetmode. manualreset); // The eventresetmode includes manual and automatic semaphore setting;
// If the value is false, no signal is generated by default. If the value is true, a signal is generated by default. Corresponding classes autoresetevent and manualresetevent
Static void main (string [] ARGs) {program P = new program (); thread T0 = new thread (New threadstart (P. writethread); thread T1 = new thread (New threadstart (P. readthread); t1.start (); t0.start (); thread T3 = new thread (New threadstart (P. aa); t3.start (); console. readline ();} private void writethread () {// allow other threads to block myeventwaithandle. reset (); // obtain the signal and let other wait processes the Wait Status console. writeline ("T1"); n1 = 1; N2 = 2; N3 = 3; myeventwaithandle. set (); // allow other waiting threads to continue} private void readthread () {myeventwaithandle. waitone (); // blocks the current thread until the console receives the signal. writeline ("{0} + {1} + {2} = {3}", N1, N2, N3, N1 + N2 + N3);} private void AA () {myeventwaithandle. waitone (); // blocks the current thread until it receives the string AA = "";}
// The difference between autoresetevent and manualresetevent is that after waitone, it will automatically become stateless, but not manually. If the following instances are set to manual, they can be executed.
Automatic. One of the readthread and AA methods cannot be executed because waitone changes to the signal state after the signal is obtained automatically.
}
2.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.
Pay attention to the usage of lock on msdn,Do not lock the public type; otherwise, the instance will be out of the control scope of the Code.
3. Monitor class
Lock is an encapsulation of enter and exit of monitor, and it is more concise to use.The combination of the enter () and exit () Methods of the monitor class 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.
Class Program
{Private static object obja = new object (); Private Static object objb = new object (); static void main (string [] ARGs) {thread threada = new thread (Locka ); thread threadb = new thread (lockb); threada. start (); threadb. start (); thread. sleep (1, 4000); console. writeline ("thread end"); console. readline ();} public static void Locka () {If (Monitor. tryenter (obja, 1000) {thread. sleep (1000); If (Monitor. tryenter (objb, 2000) {Monitor. exit (objb);} else {console. writeline ("lockb timeout");} monitor. exit (obja);} console. writeline ("Locka");} public static void lockb () {If (Monitor. tryenter (objb, 2000) {thread. sleep (2000); If (Monitor. tryenter (obja, 1000) {Monitor. exit (obja);} else {console. writeline ("Locka timeout");} monitor. exit (objb);} console. writeline ("lockb ");}}
There is no deadlock, but there is a timeout, so no deadlock will occur.
4 mutex
The name of eventwaithandle is much different from that of mutex, but it is a brother of mutex-both it and mutex are subclasses of waithandle, and their usage is similar.