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

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

Monitor.Enter

  
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();
    }
}


Monitor.Exit

  

/*
Code revised from Book published by 
(C) Copyright 1992-2006 by Deitel &amp; 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 );
   }
}


Monitor.Pulse

  
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();
    }
}


Monitor.TryEnter

  
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();
    }
}