Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It looks like you need <a href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.wait" rel="noreferrer">Monitor.Wait</a> and <a href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.pulse" rel="noreferrer">Monitor.Pulse</a>. There's a <a href="http://www.albahari.com/threading/part4.aspx#_How_to_Use_Wait_and_Pulse" rel="noreferrer">free eBook</a> out there on Threading (there are probably many but this one helped me).</p> <p>You can use a static object to lock on, and then have your threads call <code>Monitor.Pulse</code> to signal that they are "done with their turn" and <code>Monitor.Wait</code> to "wait for their next turn". Here's an example implementation using your basic code:</p> <pre><code>public class Class1 { // Use this to syncrhonize threads private static object SyncRoot = new object(); // First "turn" goes to thread 1 private static int threadInControl = 1; public static void thread1() { lock(SyncRoot) // Request exclusive access to SyncRoot { Console.WriteLine("1"); GiveTurnTo(2); // Let thread 2 have a turn WaitTurn(1); // Wait for turn to be given to thread 1 Console.WriteLine("t2 has printed 1, so we now print 2"); GiveTurnTo(2); // Let thread 2 have a turn WaitTurn(1); // Wait for turn to be given to thread 1 Console.WriteLine("t2 has printed 2, so we now print 3"); GiveTurnTo(2); // Let thread 2 have a turn } } public static void thread2() { lock(SyncRoot) // Request exclusive access to SyncRoot { WaitTurn(2); // Wait for turn to be given to thread 2 Console.WriteLine("t1 has printed 1, so we now print 1"); GiveTurnTo(1); // Let thread 1 have a turn WaitTurn(2); // Wait for turn to be given to thread 2 Console.WriteLine("t1 has printed 2, so we now print 2"); GiveTurnTo(1); // Let thread 1 have a turn WaitTurn(2); // Wait for turn to be given to thread 2 Console.WriteLine("t1 has printed 3, so we now print 3"); GiveTurnTo(1); // Let thread 1 have a turn } } // Wait for turn to use SyncRoot object public static void WaitTurn(int threadNum) { // While( not this threads turn ) while (threadInControl != threadNum) { // "Let go" of lock on SyncRoot and wait utill // someone finishes their turn with it Monitor.Wait(SyncRoot); } } // Pass turn over to other thread public static void GiveTurnTo(int nextThreadNum) { threadInControl = nextThreadNum; // Notify waiting threads that it's someone else's turn Monitor.Pulse(SyncRoot); } public static void void Main() { Thread t1 = new Thread(new ThreadStart(() =&gt; Class1.thread1())); Thread t2 = new Thread(new ThreadStart(() =&gt; Class1.thread2())); t1.Start(); t2.Start(); t2.Join(); t1.Join(); } } </code></pre> <p>As for using the <a href="http://msdn.microsoft.com/en-us/library/c5kehkcz%28v=VS.71%29.aspx" rel="noreferrer">lock keyword</a>, it is not limited to synchronization within the same function. Lock "guarantees" exclusive access to a resource (object) to a single thread (by exclusive, I mean that only one thread can obtain a lock on that resource at a time, locking does not prevent other threads from simply accessing the object itself).</p> <p>To simplify it, <code>lock(someObject)</code> is like a thread getting in line to use <code>someOject</code> and then waiting until all other threads in front of it have finished their turn before continuing. A thread ends its "turn" when it leaves the scope of the lock statement (unless you add things like <code>Monitor.Pulse</code> or <code>Monitor.Wait</code>).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload