資源描述:
《java并發(fā)編程(13):生產(chǎn)者—消費者模型(含代碼)-編程開發(fā)技術(shù)》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在工程資料-天天文庫。
1、Java并發(fā)編程(13):生產(chǎn)者一消費者模型(含代碼)-編程開發(fā)技術(shù)Java并發(fā)編程(13):生產(chǎn)者一消費者模型(含代碼)原文出處:蘭亭風雨生產(chǎn)者消費者問題是線程模型屮的經(jīng)典問題:生產(chǎn)者和消費者在同一時間段內(nèi)共用同一存儲空間,生產(chǎn)者向空間里生產(chǎn)數(shù)據(jù),而消費者取走數(shù)據(jù)。這里實現(xiàn)如下情況的生產(chǎn)-消費模型:生產(chǎn)者不斷交替地生產(chǎn)兩組數(shù)據(jù)“姓名-1->內(nèi)容-1”,“姓名-2->內(nèi)容-2”,消費者不斷交替地取得這兩組數(shù)據(jù),這里的“姓名-1”和“姓名-2”模擬為數(shù)據(jù)的名稱,“內(nèi)容-1”和“內(nèi)容-2”模擬為數(shù)據(jù)的內(nèi)容。由于本程序中牽
2、扯到線程運行的不確定性,因此可能會出現(xiàn)以下問題:1、假設(shè)生產(chǎn)者線程剛向數(shù)據(jù)存儲空間添加了數(shù)據(jù)的名稱,還沒有加入該信息的內(nèi)容,程序就切換到了消費者線程,消費者線程將把信息的名稱和上一個信息的內(nèi)容聯(lián)系在一起;2、生產(chǎn)者生產(chǎn)了若干次數(shù)據(jù),消費者才開始取數(shù)據(jù),或者是,消費者取完一次數(shù)據(jù)后,還沒等生產(chǎn)者放入新的數(shù)據(jù),乂重復取出了已取過的數(shù)據(jù)。問題1很明顯要靠同步來解決,問題2則需要線程間通信,生產(chǎn)者線程放入數(shù)據(jù)后,通知消費者線程取岀數(shù)據(jù),消費者線程取出數(shù)據(jù)后,通知生產(chǎn)者線程生產(chǎn)數(shù)據(jù),這里用wait/notify機制來實現(xiàn)。詳細
3、的實現(xiàn)代碼如下:classInfo{//定義信息類privateStringname="name";//定義name屬性,為了與下面set的name屬性區(qū)別開privatcStringcontent="contcnt〃;//定義contcnt屬性,為了與下而set的content屈性區(qū)別開privatebooleanflag=true;//設(shè)置標志位,初始時先生產(chǎn)publicsynchronizedvoidset(Stringname,Stringcontent){wh訂e(!flag){try{super,wait
4、();}catch(IntenruptedExceptione){e.printStackTrace();this.setName(name);//設(shè)置名稱try{Thread,sleep(300);}catch(JLnterruptedExceptione){e.printstackTrace();}this.setContent(content);//設(shè)置內(nèi)容flag二false;//改變標志位,表示口J以取走super?notify();}publicsynchronizedvoidget(){while(fl
5、ag){try{super?wait();}catch(InterruptedExceptione){e.printStackTrace();}}try{Thread,sleep(300);}catch(InterruptedExceptione){e.printStackTrace();}System?out?println(this?getNameO+"-->"+this?getContent());flag=true;//改變標志位,表示可以生產(chǎn)super,notify();}publicvoidsetName
6、(Stringname){this?name=name;}publicvoidsetContent(Stringcontent){this.content二content;}publicStringgetName(){returnthis.name;}publicStringgetContent(){returnthis?content;}}classProducerimplementsRunnable{//通過Runnable實現(xiàn)多線程privateInfoinfo=null;//保存Info引用publicPro
7、ducer(Infoinfo){this,info二info;}publicvoidrun(){booleanflag=true;//定義標記位for(inti二0;i〈10;i++){if(flag){this.info,set(”姓名--1〃,"內(nèi)容--1");//設(shè)置名稱flag二false;}else{this.info,set(z,姓名--2〃,〃內(nèi)容--2〃);//設(shè)置名稱flag二true;}}}}classConsumerimplementsRunnable{privatcInfoinfo二null;
8、publicConsumer(Infoinfo){this.info=info;}publicvoidrun(){for(inti=0;i<10;i++){this?info,get();}}}publicclassThrcadCascDemo03{publicstaticvoidmain(Stringargs[]){Infoinfo=newI