Csharp/C Sharp by API/System.Threading/Monitor

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

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>