Csharp/C Sharp by API/System.Threading/Monitor
Monitor.Enter
<source lang="csharp"> using System; using System.Threading;
public class EnterExit {
private int result = 0; public void NonCriticalSection() { Console.WriteLine("Entered Thread " + Thread.CurrentThread.GetHashCode()); for (int i = 1; i <= 5; i++) { Console.WriteLine("Result = " + result++ + " ThreadID " + Thread.CurrentThread.GetHashCode()); Thread.Sleep(1000); } Console.WriteLine("Exiting Thread " + Thread.CurrentThread.GetHashCode()); } public void CriticalSection() { Monitor.Enter(this); Console.WriteLine("Entered Thread " + Thread.CurrentThread.GetHashCode()); for (int i = 1; i <= 5; i++) { Console.WriteLine("Result = " + result++ + " ThreadID " + Thread.CurrentThread.GetHashCode()); Thread.Sleep(1000); } Console.WriteLine("Exiting Thread " + Thread.CurrentThread.GetHashCode()); Monitor.Exit(this); } public static void Main(String[] args) { EnterExit e = new EnterExit(); Thread nt1 = new Thread(new ThreadStart(e.NonCriticalSection)); nt1.Start(); Thread nt2 = new Thread(new ThreadStart(e.NonCriticalSection)); nt2.Start(); Thread ct1 = new Thread(new ThreadStart(e.CriticalSection)); ct1.Start(); Thread ct2 = new Thread(new ThreadStart(e.CriticalSection)); ct2.Start(); }
}
</source>
Monitor.Exit
<source lang="csharp">
/* Code revised from Book published by (C) Copyright 1992-2006 by Deitel & Associates, Inc. and Pearson Education, Inc. All Rights Reserved.
- /
using System; using System.Threading; public class SynchronizedBuffer {
private int buffer = -1; private int occupiedBufferCount = 0; public int Buffer { get { Monitor.Enter( this ); if ( occupiedBufferCount == 0 ) { Console.WriteLine(Thread.CurrentThread.Name + " tries to read." ); DisplayState( "Buffer empty. " +Thread.CurrentThread.Name + " waits." ); Monitor.Wait( this ); } --occupiedBufferCount; DisplayState( Thread.CurrentThread.Name + " reads " + buffer ); Monitor.Pulse( this ); int bufferCopy = buffer; Monitor.Exit( this ); return bufferCopy; } set { Monitor.Enter( this ); if ( occupiedBufferCount == 1 ) { Console.WriteLine(Thread.CurrentThread.Name + " tries to write." ); DisplayState( "Buffer full. " + Thread.CurrentThread.Name + " waits." ); Monitor.Wait( this ); } buffer = value; ++occupiedBufferCount; DisplayState( Thread.CurrentThread.Name + " writes " + buffer ); Monitor.Pulse( this ); Monitor.Exit( this ); } } public void DisplayState( string operation ) { Console.WriteLine( "{0,-35}{1,-9}{2}\n",operation, buffer, occupiedBufferCount ); } static void Main( string[] args ) { SynchronizedBuffer shared = new SynchronizedBuffer(); Random random = new Random(); Console.WriteLine( "{0,-35}{1,-9}{2}\n","Operation", "Buffer", "Occupied Count" ); shared.DisplayState( "Initial state" ); Producer producer = new Producer( shared, random ); Consumer consumer = new Consumer( shared, random ); Thread producerThread = new Thread( new ThreadStart( producer.Produce ) ); producerThread.Name = "Producer"; Thread consumerThread = new Thread( new ThreadStart( consumer.Consume ) ); consumerThread.Name = "Consumer"; producerThread.Start(); consumerThread.Start(); }
} public class Consumer {
private SynchronizedBuffer sharedLocation; private Random randomSleepTime; public Consumer( SynchronizedBuffer shared, Random random ) { sharedLocation = shared; randomSleepTime = random; } public void Consume() { int sum = 0; for ( int count = 1; count <= 10; count++ ) { Thread.Sleep( randomSleepTime.Next( 1, 1001 ) ); sum += sharedLocation.Buffer; } Console.WriteLine("{0} read values totaling: {1}.\nTerminating {0}.",Thread.CurrentThread.Name, sum ); }
} public class Producer {
private SynchronizedBuffer sharedLocation; private Random randomSleepTime; public Producer( SynchronizedBuffer shared, Random random ) { sharedLocation = shared; randomSleepTime = random; } public void Produce() { for ( int count = 1; count <= 10; count++ ) { Thread.Sleep( randomSleepTime.Next( 1, 1001 ) ); sharedLocation.Buffer = count; } Console.WriteLine( "{0} done producing.\nTerminating {0}.",Thread.CurrentThread.Name ); }
}
</source>
Monitor.Pulse
<source lang="csharp"> using System; using System.Threading; class MessageBoard {
private String messages = "no messages"; public void Reader() { try { Monitor.Enter(this); if (messages == "no messages") { Console.WriteLine("{0} {1}",Thread.CurrentThread.Name, messages); Console.WriteLine("{0} waiting",Thread.CurrentThread.Name); Monitor.Wait(this); } Console.WriteLine("{0} {1}",Thread.CurrentThread.Name, messages); } finally { Monitor.Exit(this); } } public void Writer() { try { Monitor.Enter(this); messages = "Greetings!"; Console.WriteLine("{0} Done writing message",Thread.CurrentThread.Name); Monitor.Pulse(this); } finally { Monitor.Exit(this); } } public static void Main() { MessageBoard myMessageBoard = new MessageBoard(); Thread reader = new Thread(new ThreadStart(myMessageBoard.Reader)); reader.Name = "ReaderThread:"; Thread writer = new Thread(new ThreadStart(myMessageBoard.Writer)); writer.Name = "WriterThread:"; reader.Start(); writer.Start(); }
}
</source>
Monitor.TryEnter
<source lang="csharp"> using System; using System.Threading; public class TryEnter {
public void CriticalSection() { bool b = Monitor.TryEnter(this, 1000); Console.WriteLine("Thread " + Thread.CurrentThread.GetHashCode() + " TryEnter Value " + b); for (int i = 1; i <= 3; i++) { Thread.Sleep(1000); Console.WriteLine(i + " " + Thread.CurrentThread.GetHashCode() + " "); } Monitor.Exit(this); } public static void Main() { TryEnter a = new TryEnter(); Thread t1 = new Thread(new ThreadStart(a.CriticalSection)); Thread t2 = new Thread(new ThreadStart(a.CriticalSection)); t1.Start(); t2.Start(); }
}
</source>