C # multi-thread usage 5-Collaborative Monitor between threads,
Previously, we used the lock shortcut to achieve multi-threaded sharing of the same resource. In C #, lock is actually a simplified version of the Monitor operation.
The following uses Monitor to complete the previous lock function. You can compare it here:
private static void MultiThreadSynergicWithMonitor() { int[] array = new int[3]; Thread producer = new Thread(() => { int count = 0; Random random = new Random(); while (true) { if (10 == count) break; Monitor.Enter(array); array[0] = random.Next(10); array[1] = random.Next(10); array[2] = random.Next(10); count++; Console.WriteLine(String.Format("{0} work count:{1}。{2}-{3}-{4}", Thread.CurrentThread.Name, count, array[0], array[1], array[2])); Monitor.Exit(array); } }) { Name = "producer" }; Thread customer = new Thread(() => { int count = 0; while (true) { if (10 == count) break; Monitor.Enter(array); count++; Console.WriteLine(String.Format("{0} work count:{1}。{2}-{3}-{4}", Thread.CurrentThread.Name, count, array[0], array[1], array[2])); array[0] = 0; array[1] = 0; array[2] = 0;Monitor.Exit(array); } }) { Name = "customer" }; producer.Start(); customer.Start(); }
By comparison, you can find that lock (xx) {} is equivalent to Monitor. enter (x') and Monitor. the combination of Exit (xx) is actually the syntactic sugar of Monitor.
Therefore, Monitor is more powerful than lock in controlling thread collaboration, as shown below:
/// <Summary> // multi-thread collaboration-Monitor method // The multi-thread sharing of a single resource is successfully solved. // The synchronization problem between multiple threads is also solved. // </summary> private static void MultiThreadSynergicWithMonitor () {int [] array = new int [3]; Thread producer = new Thread () => {int count = 0; Random random = new Random (); while (true) {if (10 = count) break; Monitor. enter (array); array [0] = random. next (10); array [1] = random. next (10); array [2] = random. next (10); count ++; Console. WriteLine (String. Format ("{0} work count: {1 }. {2}-{3}-{4} ", Thread. currentThread. name, count, array [0], array [1], array [2]); Monitor. pulse (array); Monitor. wait (array);} Monitor. exit (array) ;}) {Name = "producer"}; Thread customer = new Thread () =>{ int count = 0; while (true) {if (10 = count) break; Monitor. enter (array); count ++; Console. writeLine (String. format ("{0} work count: {1 }. {2}-{3}-{4} ", Thread. currentThread. name, count, array [0], array [1], array [2]); array [0] = 0; array [1] = 0; array [2] = 0; Monitor. pulse (array); Monitor. wait (array);} Monitor. exit (array) ;}) {Name = "customer"}; producer. start (); customer. start ();}
The above code is similar to the previous lock code function, but is not the same. It achieves the alternate running of the producer thread and the customer thread (more refined than the lock method ), we recommend that you execute the actual code again, and you will easily find that the two are different.
Note:
1. Monitor. Pulse (xx) enables notification to wait for xx ResourcesA threadFrom the waiting status (waiting queue) to the ready status (ready queue), so that you are ready to call the Monitor. when a thread of the Pulse (x') function releases a resource, the released resource is immediately locked.
2. The Monitor. Wait (xx) thread that calls this method temporarily releases the locked resource and enters the waiting thread queue. Therefore, the thread temporarily interrupts subsequent code execution after calling this method. When the thread Obtains resources again,
It will return to the interruption and continue execution.
3. Monitor. pulseAll (xx) is Monitor. if you understand the extended version of Pulse (xx. pulse (xx) and know the thread status changes (changes in the queue of the thread), so understandMonitor. PulseAllIt's much simpler..
Monitor. PulseAllAll threads waiting for resources are changed from waiting to ready. If the resources are released, all ready threads will have the opportunity to obtain and execute the resources.