首先,我們定義一個被操作的對象的類Cell,在這個類裡,有兩個方法:ReadFromCell()和WriteToCell。消費者線程將調用ReadFromCell()讀取cellContents的內容並且顯示出來,生產者進程將調用WriteToCell()方法向cellContents寫入資料。
public class Cell { int cellContents; // Cell對象裡邊的內容 bool readerFlag = false; // 狀態標誌,為true時可以讀取,為false則正在寫入 public int ReadFromCell( ) { lock(this) // Lock關鍵字保證了什麼,請大家看前面對lock的介紹 { if (!readerFlag)//如果現在不可讀取 { try { file://等待WriteToCell方法中調用Monitor.Pulse()方法 Monitor.Wait(this); } catch (SynchronizationLockException e) { Console.WriteLine(e); } catch (ThreadInterruptedException e) { Console.WriteLine(e); } } Console.WriteLine("Consume: {0}",cellContents); readerFlag = false; file://重設readerFlag標誌,表示消費行為已經完成 Monitor.Pulse(this); file://通知WriteToCell()方法(該方法在另外一個線程中執行,等待中) } return cellContents; } public void WriteToCell(int n) { lock(this) { if (readerFlag) { try { Monitor.Wait(this); } catch (SynchronizationLockException e) { file://當同步方法(指Monitor類除Enter之外的方法)在非同步的代碼區被調用 Console.WriteLine(e); } catch (ThreadInterruptedException e) { file://當線程在等待狀態的時候中止 Console.WriteLine(e); } } cellContents = n; Console.WriteLine("Produce: {0}",cellContents); readerFlag = true; Monitor.Pulse(this); file://通知另外一個線程中正在等待的ReadFromCell()方法 } } } |
下面定義生產者CellProd和消費者類CellCons,它們都只有一個方法ThreadRun(),以便在Main()函數中提供給線程的ThreadStart代理對象,作為線程的入口。
public class CellProd { Cell cell; // 被操作的Cell對象 int quantity = 1; // 生產者生產次數,初始化為1 public CellProd(Cell box, int request) { //建構函式 cell = box; quantity = request; } public void ThreadRun( ) { for(int looper=1; looper<=quantity; looper++) cell.WriteToCell(looper); file://生產者向操作對象寫入資訊 } } public class CellCons { Cell cell; int quantity = 1; public CellCons(Cell box, int request) { cell = box; quantity = request; } public void ThreadRun( ) { int valReturned; for(int looper=1; looper<=quantity; looper++) valReturned=cell.ReadFromCell( );//消費者從操作對象中讀取資訊 } } |