java多线程 生产者消费者_java多线程之生产者消费者经典问题 - 很不错的范例
/**生產(chǎn)者消費(fèi)者問(wèn)題,涉及到幾個(gè)類(lèi)
*?第一,這個(gè)問(wèn)題本身就是一個(gè)類(lèi),即主類(lèi)
*?第二,既然是生產(chǎn)者、消費(fèi)者,那么生產(chǎn)者類(lèi)和消費(fèi)者類(lèi)就是必須的
*?第三,生產(chǎn)什么,消費(fèi)什么,所以物品類(lèi)是必須的,這里是饅頭類(lèi)
*?第四,既然是線(xiàn)程,那么就不是一對(duì)一的,也就是說(shuō)不是生產(chǎn)一個(gè)消費(fèi)一個(gè),既然這樣,多生產(chǎn)的往哪里放,
*??????現(xiàn)實(shí)中就是筐了,在計(jì)算機(jī)中也就是數(shù)據(jù)結(jié)構(gòu),筐在數(shù)據(jù)結(jié)構(gòu)中最形象的就是棧了,因此還要一個(gè)棧類(lèi)
*/
packagethread;
publicclassProduceConsume?{
publicstaticvoidmain(String[]?args)?{
SyncStack?ss?=?newSyncStack();//建造一個(gè)裝饅頭的框
Producer?p?=?newProducer(ss);//新建一個(gè)生產(chǎn)者,使之持有框
Consume?c?=?newConsume(ss);//新建一個(gè)消費(fèi)者,使之持有同一個(gè)框
Thread?tp?=?newThread(p);//新建一個(gè)生產(chǎn)者線(xiàn)程
Thread?tc?=?newThread(c);//新建一個(gè)消費(fèi)者線(xiàn)程
tp.start();//啟動(dòng)生產(chǎn)者線(xiàn)程
tc.start();//啟動(dòng)消費(fèi)者線(xiàn)程
}
}
//饅頭類(lèi)
classSteamBread{
intid;//饅頭編號(hào)
SteamBread(intid){
this.id?=?id;
}
publicString?toString(){
return"steamBread:"+id;
}
}
//裝饅頭的框,棧結(jié)構(gòu)
classSyncStack{
intindex?=0;
SteamBread[]?stb?=?newSteamBread[6];//構(gòu)造饅頭數(shù)組,相當(dāng)于饅頭筐,容量是6
//放入框中,相當(dāng)于入棧
publicsynchronizedvoidpush(SteamBread?sb){
while(index==stb.length){//筐滿(mǎn)了,即棧滿(mǎn),
try{
this.wait();//讓當(dāng)前線(xiàn)程等待
}?catch(InterruptedException?e)?{
//?TODO?Auto-generated?catch?block
e.printStackTrace();
}
}
this.notify();//喚醒在此對(duì)象監(jiān)視器上等待的單個(gè)線(xiàn)程,即消費(fèi)者線(xiàn)程
stb[index]?=?sb;
this.index++;
}
//從框中拿出,相當(dāng)于出棧
publicsynchronizedSteamBread?pop(){
while(index==0){//筐空了,即棧空
try{
this.wait();
}?catch(InterruptedException?e)?{
//?TODO?Auto-generated?catch?block
e.printStackTrace();
}
}
this.notify();
this.index--;//push第n個(gè)之后,this.index++,使棧頂為n+1,故return之前要減一
returnstb[index];
}
}
//生產(chǎn)者類(lèi),實(shí)現(xiàn)了Runnable接口,以便于構(gòu)造生產(chǎn)者線(xiàn)程
classProducerimplementsRunnable{
SyncStack?ss?=?null;
Producer(SyncStack?ss){
this.ss?=?ss;
}
@Override
publicvoidrun()?{
//?開(kāi)始生產(chǎn)饅頭
for(inti=0;i<20;i++){
SteamBread?stb?=?newSteamBread(i);
ss.push(stb);
System.out.println("生產(chǎn)了"+stb);
try{
Thread.sleep(10);//每生產(chǎn)一個(gè)饅頭,睡覺(jué)10毫秒
}?catch(InterruptedException?e)?{
//?TODO?Auto-generated?catch?block
e.printStackTrace();
}
}
}
}
//消費(fèi)者類(lèi),實(shí)現(xiàn)了Runnable接口,以便于構(gòu)造消費(fèi)者線(xiàn)程
classConsumeimplementsRunnable{
SyncStack?ss?=?null;
publicConsume(SyncStack?ss)?{
super();
this.ss?=?ss;
}
@Override
publicvoidrun()?{
//?TODO?Auto-generated?method?stub
for(inti=0;i<20;i++){//開(kāi)始消費(fèi)饅頭
SteamBread?stb?=?ss.pop();
System.out.println("消費(fèi)了"+stb);
try{
Thread.sleep(100);//每消費(fèi)一個(gè)饅頭,睡覺(jué)100毫秒。即生產(chǎn)多個(gè),消費(fèi)一個(gè)
}?catch(InterruptedException?e)?{
//?TODO?Auto-generated?catch?block
e.printStackTrace();
}
}
}
}
運(yùn)行結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的java多线程 生产者消费者_java多线程之生产者消费者经典问题 - 很不错的范例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 不是单组分组函数「建议收藏」
- 下一篇: java readline最后一行_ja