Thread Synchronization is often encountered in multi-threaded programs:
Scenario 1
After the main thread starts multiple sub-threads, the main thread needs to wait until all the sub-threads have completed the execution before the main thread can further execute down.
C # provides the ManualResetEvent class to facilitate thread synchronization.
ManualResetEvent.WaitAll(New WaitHandle [] {});
The WaitAll static method can block the execution of the current thread until each thread in WaitHandle [] sends a signal for blocking and unblocking.
You can pass a Boolean value to the constructor to control the initial status of ManualResetEvent. If the initial status is terminated, the value is true; otherwise, the value is false.
ManualResetEvent.Set() The method sends a blocking termination signal. When other threads receive a signal from the thread to block the termination, the program continues to run.
Scenario: the main thread needs to sum the data produced by sub-thread 1 with the data generated by sub-thread 2. The main thread starts thread 1 to wait for data generation 1 and start thread 2 to wait for data generation 2. Only when
After data 1 and 2 are generated, the main thread can sum the data.
The Code is as follows:
Using System; using System. collections. generic; using System. linq; using System. text; using System. threading; using System. diagnostics; namespace ThreadStudy. hbb0b0 {/// <summary> /// example shows how the main thread continues to execute after all the auxiliary threads are executed. /// The main thread starts the auxiliary thread 1 to generate the addition 1, and starts the auxiliary thread 2 to generate the addition 2 // after the main thread waits for the addition generated by the auxiliary thread 1 and the auxiliary thread 2, add the number // and output the result. /// </Summary> class Program {delegate int operateNumber (int a, int B); delegate int generateNumber (int a); static int result1; static int result2; static void Main (string [] args) {// ManualResetEvent m1 = new ManualResetEvent (false ); // ManualResetEvent m2 = new ManualResetEvent (false); generateNumber g1 = ThreadTool. generateNumber; generateNumber g2 = ThreadTool. generateNumber; AsyncCallback g1_callback = delegate (IAsyncResult ar) {result1 = g1.EndInvoke (ar); Console. writeLine ("thread id: {0} current number: {1} block stop", Thread. currentThread. managedThreadId, result1); // The m1.Set () ;}; AsyncCallback g2_callback = delegate (IAsyncResult ar) {result2 = g2.EndInvoke (ar); Console. writeLine ("thread id: {0} current number: {1} block stop", Thread. currentThread. managedThreadId, result2); // The m2.Set () ;}; Console. writeLine ("generate numbers:"); // auxiliary thread 1 starts g1.BeginInvoke (10, g1_callback, null); // auxiliary thread 2 starts g2.BeginInvoke (100, g2_callback, null ); // The main thread waits for all the auxiliary threads to return to ManualResetEvent. waitAll (new WaitHandle [] {m1, m2}); int sum = ThreadTool. sum (result1, result2); Console. writeLine ("{0} + {1} = {2}", result1, result2, sum); Console. read ();}} public class ThreadTool {// <summary> // generate a number /// </summary> /// <param name = "maxNum"> </param> /// <returns> </returns> static public int GenerateNumber (int maxNum) {Console. writeLine ("thread Id: {0} generate number", Thread. currentThread. managedThreadId); Thread. sleep (5000); int result = new Random (int) DateTime. now. ticks ). next (maxNum); return result ;} /// <summary> /// accumulate result /// </summary> /// <param name = "a"> </param> /// <param name = "B"> </param> // <returns> </returns> static public int sum (int, int B) {Console. writeLine ("thread Id: {0} gernerate number", Thread. currentThread. managedThreadId); Thread. sleep (6000); return a + B ;}}}
Scenario 2:
The main thread starts thread 1 and sub-thread 2. As long as sub-thread 1 or sub-thread 2 completes execution, the main thread can continue execution.
The Code is as follows:
Using System; using System. collections. generic; using System. linq; using System. text; using System. threading; namespace ThreadWaitOne {class ThreadStartParameterInfo {// <summary> // thread signal // </summary> public ManualResetEvent m_mr; /// <summary> /// thread wait time /// </summary> public int m_waitTicks; public ThreadStartParameterInfo (ManualResetEvent mr, int waitTicks) {m_mr = mr; m_waitTicks = waitTicks;} public class ThreadTool {private object m_SyncObject = new object (); private int currentThreadId =-1; public void Main () {for (int I = 0; I <5; I ++) {ManualResetEvent mr1 = new ManualResetEvent (false); ManualResetEvent mr2 = new ManualResetEvent (false); ManualResetEvent mr3 = new ManualResetEvent (false ); parameterizedThreadStart pts1 = new ParameterizedThreadStart (this. generateNumber); ParameterizedThreadStart pts2 = new ParameterizedThreadStart (this. generateNumber); ParameterizedThreadStart pts3 = new ParameterizedThreadStart (this. generateNumber); Thread ts1 = new Thread (pts1); Thread ts2 = new Thread (pts1); Thread ts3 = new Thread (pts1); ts1.Start (new ThreadStartParameterInfo (mr1, 3010); ts2.Start (new ThreadStartParameterInfo (mr2, 3020); ts3.Start (new ThreadStartParameterInfo (mr3, 3030); // The main thread waits for any thread, after any thread sends a blocking completion signal, the main thread can continue to execute ManualResetEvent. waitAny (new WaitHandle [] {mr1, mr2, mr3}); Console. writeLine ("Main Thread: The fast thread: {0}", currentThreadId) ;}} public void GenerateNumber (object resetEvent) {ThreadStartParameterInfo threadInfo = resetEvent as ThreadStartParameterInfo; // ManualResetEvent mr = resetEvent as ManualResetEvent; Console. writeLine ("thread Id: {0} wait: {1} generate number start :..... ", Thread. currentThread. managedThreadId, threadInfo. m_waitTicks); Thread. sleep (threadInfo. m_waitTicks); int radomNumber = new Random (int) DateTime. now. ticks ). next (1000); lock (m_SyncObject) {currentThreadId = Thread. currentThread. managedThreadId;} Console. writeLine ("thread Id: {0} generate number: {1}", Thread. currentThread. managedThreadId, radomNumber); threadInfo. m_mr.Set ();}}}