// 读者写者问题
using System; using System.Threading;
public class Book{
private int[] pages; private bool aWriterWait = false; private int readerCount = 0;
private object mutex = new Object(); // 控制对 readerCount 的访问 private object db = new Object(); // 控制对 pages 的访问 private object obj = new Object(); // 控制对 aWriterWait 的访问
public Book(int numOfPages){ pages = new int[numOfPages]; }
public int NumOfPages{ get{ return pages.Length; //常量,无须同步 } }
public int this[int index]{ get{ lock(obj){ while( aWriterWait ){ Monitor.Wait(obj); } }
lock(mutex){ // readerCount的锁 // 检查是否为第一个读者 readerCount++; if(readerCount == 1) Monitor.Enter(db); } int valueCopy = pages[index]; // 读取一个数据
Console.WriteLine( Thread.CurrentThread.Name + " 读了 第" + (index + 1) + "页,他读到的数据是" + valueCopy );
DisplayContent();
lock(mutex){ readerCount--; if(readerCount == 0) Monitor.Exit(db); }
return valueCopy; } set{ lock (obj){ aWriterWait = true; }
lock(db){ // 阻止其他的写者去写书 pages[index] = value; Console.WriteLine( Thread.CurrentThread.Name + "把" + value + "写到第" + (index + 1) + "页"); DisplayContent(); }
lock(obj){ aWriterWait = false; Monitor.PulseAll(obj); // 通知等待的读者 } } } private void DisplayContent(){ Console.WriteLine("{0,-35}","书的内容是:"); for(int i = 0;i < pages.Length;i++){ Console.Write("{0,-9}",pages[i]); } Console.WriteLine("\r\n"); } }
public class Reader{ private Book book; private Random rand; public Reader(Book b,Random random){ book = b; rand = random; } public void Read(){ for (int i=0; i < 5; i++){ int p = rand.Next(0,book.NumOfPages); int a = book[p]; Thread.Sleep(rand.Next(0,100)); } } }
public class Writer{ private Book book; private Random rand; public Writer(Book b,Random random){ book = b; rand = random; } public void Write(){ for(int i = 0;i < 5;i++){ int p = rand.Next(0,book.NumOfPages); book[p] = rand.Next(50,100); Thread.Sleep(rand.Next(0,100)); } } }
public class Test{ public static void Main(string[] args){ Book book = new Book(5); Random random = new Random(); string[] readerNames = {"猪八戒","唐僧","沙和尚"}; string[] writerNames = {"观音菩萨","孙悟空","玉皇大帝"};
Thread[] readerThreads = new Thread[3]; Thread[] writerThreads = new Thread[3];
for(int i = 0;i < 3;i++){ Reader reader = new Reader(book,random); readerThreads[i] = new Thread(new ThreadStart(reader.Read)); readerThreads[i].Name = readerNames[i]; Writer writer = new Writer(book,random); writerThreads[i] = new Thread(new ThreadStart(writer.Write)); writerThreads[i].Name = writerNames[i];
} for (int i=0; i<3; i++){ readerThreads[i].Start(); writerThreads[i].Start(); } } } 
|