Csharp/C Sharp by API/System.Threading/Monitor
Версия от 15:31, 26 мая 2010; (обсуждение)
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 & 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();
}
}