Multi-thread synchronization and lock
This article mainly discusses lock, autoeventset, and moniter.
The Code is as follows:
Using system;
Using system. Collections. Generic;
Using system. LINQ;
Using system. text;
Using system. Threading;
Namespace consoleapplication1
{
Class Program
{
Private Static autoresetevent autoreset = new autoresetevent (false );
Static int countnum = 0; // counter
Static object lockobj = new object (); // static Lock Object
Static void main (string [] ARGs)
{
// Test autoresetevent and lock object or static object begin
Thread thread1 = new thread (New parameterizedthreadstart (wirte1 ));
Thread1.start (1 );
Thread thread2 = new thread (wirte1 );
Thread2.start (2 );
// --- Test end ---
// Test monitor begin
// Thread thread3 = new thread (wirte2 );
// Thread3.start (3 );
// Thread thread5 = new thread (wirte2 );
// Thread5.start (5 );
// -- End ---
Thread thread4 = new thread (New threadstart (wirte4 ));
Thread4.start ();
Console. Readline ();
}
Public static void wirte1 (object index)
{
Autoreset. waitone (); // blocking until the signal is received
Console. writeline (index. tostring () + "Enter lock before ");
// Lock (new object () // This lock can only allow one thread to enter the locked code block at a time, but other threads can be grabbed once.
Lock (lockobj) // after locking, only one thread enters until the code in the block is executed.
{
Console. writeline (index. tostring () + "Enter lock after ");
While (countnum <50)
{
Console. writeline (countnum. tostring () + "index:" + index. tostring ());
Thread. Sleep (500 );
// Autoreset. Reset ();
Countnum ++;
}
}
// Autoreset. Set ();
}
Public static void wirte2 (object index)
{
Bool isrealse = false;
Lock (lockobj)
{
Console. writeline (index. tostring () + "Enter lock after ");
While (countnum <50)
{
If (isrealse)
{
Monitor. Wait (lockobj); // block the current thread
}
Console. writeline (countnum. tostring () + "index:" + index. tostring ());
Thread. Sleep (500 );
// Autoreset. Reset ();
Countnum ++;
If (countnum> 27)
{
Monitor. pulseall (lockobj); // cancel blocking and the current lock is invalid.
}
If (countnum> 30)
{
Isrealse = true;
}
}
}
}
Public static void wirte3 ()
{
For (INT I = 0; I <30; I ++)
{
Console. writeline (I. tostring () + "thread3 ");
Thread. Sleep (500 );
}
}
Public static void wirte4 ()
{
Lock (lockobj)
{
For (INT I = 0; I <30; I ++)
{
Console. writeline (I. tostring () + "thread4 ");
Thread. Sleep (500 );
If (I> 25)
{
Autoreset. Set (); // The confidence number is true, and the blocked thread can run
}
}
}
}
}
}
Write1 is executed for thread 1 and 2 and is blocked until thread 4 sends a signal. The thread 1 and 2 can run the thread that obtains the execution right after receiving the signal.
Change main
Static void main (string [] ARGs)
{
// Test autoresetevent and lock object or static object begin
// Thread thread1 = new thread (New parameterizedthreadstart (wirte1 ));
// Thread1.start (1 );
// Thread thread2 = new thread (wirte1 );
// Thread2.start (2 );
// --- Test end ---
// Test monitor begin
Thread thread3 = new thread (wirte2 );
Thread3.start (3 );
Thread thread5 = new thread (wirte2 );
Thread5.start (5 );
// -- End ---
Thread thread4 = new thread (New threadstart (wirte4 ));
Thread4.start ();
Console. Readline ();
}
For thread 3, 5, execute write2, thread 4, execute wirte4, first get lock first, if thread 4 gets the lock, wait until the execution is complete, if the thread gets lock at 3, 5, it will be blocked after> 30, but monitor at> 27. pulseall (lockobj); the blocking has been canceled and lock does not work, So monitor. wait (lockobj); does not play a blocking effect (a high probability). If write2 only has one thread to execute, it will certainly be blocked at> 30.
Summary:
1 lock new object is only valid for the current time, and then all the waiting threads may obtain the lock
2 Lock static object if multiple threads use the same object lock, the operation is obtained first, and other waits
3 autoresetevent waitone blocking, set release signal, the blocked thread can get the operation right
4 monitor. pulseall (lockobj); cancel blocking and the current lock is released
5 monitor. Wait (lockobj); blocks the current thread,
The above is the test result of vs2008 and win7. If any error is found, please correct it to avoid misleading everyone. Thank you!