The mutex class in the system. Threading namespace is used to control the connections between multiple threads without conflict or repetition. We can regard mutex as a taxi and passengers as a thread. The passenger first waits for the car, then gets on the bus, and finally gets off the bus. When a passenger is on the bus, other passengers can only get on the bus after they get off the bus. This is also the relationship between the thread and the mutex object. The thread uses mutex. the waitone () method waits for the mutex object to be released. If the mutex object it waits for is released, it automatically owns the object until it calls mutex. the releasemutex () method releases this object. During this period, other threads that want to obtain this mutex object only have to wait.
The following example uses a mutex object to synchronize four threads. The main thread waits for the end of the four threads, and the running of these four threads is associated with two mutex objects. The autoresetevent class object is also used, which can be understood as a signal lamp. Here, its signal state is used to indicate the end of a thread.
Mutex classProgramExample:
UsingSystem;
UsingSystem. Threading;
NamespaceThreadexample
{
Public ClassMutexsample
{
StaticMutex GM1;
StaticMutex gm2;
Const IntIters = 100;
StaticAutoresetevent event1 =NewAutoresetevent (False);
StaticAutoresetevent event2 =NewAutoresetevent (False);
StaticAutoresetevent event3 =NewAutoresetevent (False);
StaticAutoresetevent event4 =NewAutoresetevent (False);
Public Static VoidMain (string [] ARGs)
{
Console. writeline ("Mutex sample");
// Create a mutex object and name it mymutex
GM1 =NewMutex (True,"Mymutex");
// Create an unnamed mutex object.
Gm2 =NewMutex (True);
Console. writeline ("-Main owns GM1 and gm2");
// Defines the autoresetevent object for the following threads T1, T2, T3, and T4
Autoresetevent [] EVS =NewAutoresetevent [] {event1, event2, event3, event4 };
Mutexsample TM =NewMutexsample ();
Thread T1 =NewThread (NewThreadstart (TM. t1start ));
Thread t2 =NewThread (NewThreadstart (TM. t2start ));
Thread T3 =NewThread (NewThreadstart (TM. t3start ));
Thread t4 =NewThread (NewThreadstart (TM. t4start ));
T1.start ();// Use the mutex. waitall () method to wait for all objects in a mutex array to be released
T2.start ();// Use the mutex. waitone () method to wait for the release of GM1
T3.start ();// Use the mutex. waitany () method to wait for any object in a mutex array to be released
T4.start ();// Use the mutex. waitone () method to wait for the release of gm2
Thread. Sleep (2000 );
Console. writeline ("-Main releases GM1");
Gm1.releasemutex ();// Thread T2 and T3 finish conditions are met
Thread. Sleep (2000 );
Console. writeline ("-Main releases gm2");
Gm2.releasemutex ();// The end conditions of thread T1 and T4 are met
Waithandle. waitall (EVS );// Wait until all four threads end
Console. writeline ("Mutex sample");
}
Public VoidT1start ()
{
Console. writeline ("T1start started, mutex. waitall (mutex [])");
Mutex [] GMS =NewMutex [2];
GMS [0] = GM1;// Create a mutex array as a parameter of the mutex. waitall () method.
GMS [1] = gm2;
Mutex. waitall (GMS );// Wait until both GM1 and gm2 are released
Thread. Sleep (2000 );
Console. writeline ("T1start finished, mutex. waitall (mutex []) satisfied");
Event1.set ();// When the thread ends, set event1 to a signal state.
}
Public VoidT2start ()
{
Console. writeline ("T2start started, gm1.waitone ()");
Gm1.waitone ();// Wait for the release of GM1
Thread. Sleep (2000 );
Console. writeline ("T2start finished, gm1.waitone () satisfied");
Event2.set ();// When the thread ends, set event2 to a signal state.
}
Public VoidT3start ()
{
Console. writeline ("T3start started, mutex. waitany (mutex [])");
Mutex [] GMS =NewMutex [2];
GMS [0] = GM1;// Create a mutex array as a parameter of the mutex. waitany () method.
GMS [1] = gm2;
Mutex. waitany (GMS );// Wait for any mutex object in the array to be released
Console. writeline ("T3start finished, mutex. waitany (mutex [])");
Event3.set ();// When the thread ends, set event3 to a signal state.
}
Public VoidT4start ()
{
Console. writeline ("T4start started, gm2.waitone ()");
Gm2.waitone ();// Wait for gm2 to be released
Console. writeline ("T4start finished, gm2.waitone ()");
Event4.set ();// When the thread ends, set event4 to a signal state.
}
}
}
for thread T2, T3 runs on the condition that GM1 is released. T4 is executed after gm2 is released, and T1 is executed after both GM1 and gm2 are released. At the end of the main () function, waithandle is used to wait for the signals of all autoresetevent objects. The signals of these objects represent the end of the corresponding thread.