C#生產(chǎn)者和消費(fèi)者
下面定義C#生產(chǎn)者和消費(fèi)者,它們都只有一個(gè)方法ThreadRun(),以便在Main()函數(shù)中提供給線程的ThreadStart代理對(duì)象,作為線程的入口。
- public class CellProd
- {
- Cell cell; // 被操作的Cell對(duì)象
- int quantity = 1; // 生產(chǎn)者生產(chǎn)次數(shù),初始化為1
- public CellProd(Cell box, int request)
- {
- //構(gòu)造函數(shù)
- cell = box;
- quantity = request;
- }
- public void ThreadRun( )
- {
- for(int looper=1; looper<=quantity; looper++)
- cell.WriteToCell(looper); //生產(chǎn)者向操作對(duì)象寫入信息
- }
- }
- public class CellCons
- {
- Cell cell;
- int quantity = 1;
- public CellCons(Cell box, int request)
- {
- //構(gòu)造函數(shù)
- cell = box;
- quantity = request;
- }
- public void ThreadRun( )
- {
- int valReturned;
- for(int looper=1; looper<=quantity; looper++)
- valReturned=cell.ReadFromCell( );//消費(fèi)者從操作對(duì)象中讀取信息
- }
- }
然后在下面這個(gè)類MonitorSample的Main()函數(shù)中,我們要做的就是創(chuàng)建兩個(gè)線程分別作為C#生產(chǎn)者和消費(fèi)者,使用CellProd.ThreadRun()方法和CellCons.ThreadRun()方法對(duì)同一個(gè)Cell對(duì)象進(jìn)行操作
- public class MonitorSample
- {
- public static void Main(String[] args)
- {
- int result = 0;
- //一個(gè)標(biāo)志位,如果是0表示程序沒(méi)有出錯(cuò),如果是1表明有錯(cuò)誤發(fā)生
- Cell cell = new Cell( );
- //下面使用cell初始化CellProd和CellCons兩個(gè)類,生產(chǎn)和消費(fèi)次數(shù)均為20次
- CellProd prod = new CellProd(cell, 20);
- CellCons cons = new CellCons(cell, 20);
- Thread producer = new Thread(new ThreadStart(prod.ThreadRun));
- Thread consumer = new Thread(new ThreadStart(cons.ThreadRun));
- //生產(chǎn)者線程和消費(fèi)者線程都已經(jīng)被創(chuàng)建,但是沒(méi)有開(kāi)始執(zhí)行
- try
- {
- producer.Start( );
- consumer.Start( );
- producer.Join( );
- consumer.Join( );
- Console.ReadLine();
- }
- catch (ThreadStateException e)
- {
- //當(dāng)線程因?yàn)樗帬顟B(tài)的原因而不能執(zhí)行被請(qǐng)求的操作
- Console.WriteLine(e);
- result = 1;
- }
- catch (ThreadInterruptedException e)
- {
- //當(dāng)線程在等待狀態(tài)的時(shí)候中止
- Console.WriteLine(e);
- result = 1;
- }
- //盡管Main()函數(shù)沒(méi)有返回值,但下面這條語(yǔ)句可以向父進(jìn)程返回執(zhí)行結(jié)果
- Environment.ExitCode = result;
- }
- }
在上面的例程中,同步是通過(guò)等待Monitor.Pulse()來(lái)完成的。首先生產(chǎn)者生產(chǎn)了一個(gè)值,而同一時(shí)刻消費(fèi)者處于等待狀態(tài),直到收到生產(chǎn)者的“脈沖(Pulse)”通知它生產(chǎn)已經(jīng)完成,此后消費(fèi)者進(jìn)入消費(fèi)狀態(tài),而生產(chǎn)者開(kāi)始等待消費(fèi)者完成操作后將調(diào)用Monitor.Pulese()發(fā)出的“脈沖 ”。
事實(shí)上,這個(gè)簡(jiǎn)單的例子已經(jīng)幫助我們解決了多線程應(yīng)用程序中可能出現(xiàn)的大問(wèn)題,只要領(lǐng)悟了解決線程間沖突的基本方法,很容易把它應(yīng)用到比較復(fù)雜的程序中去。以上介紹C#生產(chǎn)者和消費(fèi)者。
【編輯推薦】