成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

java生產(chǎn)消費(fèi)者代碼 java生產(chǎn)消費(fèi)者代碼是多少

java多生產(chǎn)者和多消費(fèi)者

public static void main(String[] args) {

專注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)芒市免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了千余家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

Buffer buffer=new Buffer(); //創(chuàng)建一個(gè)臨界區(qū)對(duì)象

new Producer(buffer,100).start(); //創(chuàng)建一個(gè)生產(chǎn)者對(duì)象,并啟動(dòng)其線程

new Consumer(buffer,200).start(); //創(chuàng)建一個(gè)消費(fèi)者對(duì)象,并啟動(dòng)其線程

new Consumer(buffer,201).start(); //創(chuàng)建第二個(gè)消費(fèi)者對(duì)象,并啟動(dòng)其線程

}

這一段代碼,多加入

new Consumer(buffer,201).start(); //創(chuàng)建第二個(gè)消費(fèi)者對(duì)象,并啟動(dòng)其線程

多加一段代碼創(chuàng)建一個(gè)消費(fèi)者

多加入

new Producer(buffer,100).start();

創(chuàng)建一個(gè)生產(chǎn)者。

想要很多生產(chǎn)者和消費(fèi)者?加就是了啊。

第四個(gè)文件 Buffer.java

這個(gè)是實(shí)現(xiàn)同步的主要緩存類。想要實(shí)現(xiàn)同步

在每個(gè)方法的聲明前都加入synchronized 就行

synchronized 線程鎖,很好用的。源代碼已經(jīng)加入了

就比如

public synchronized void put(int value) { //同步方法控制臨界區(qū)內(nèi)容寫入

java多生產(chǎn)者和消費(fèi)者問題,重復(fù)生產(chǎn)消費(fèi)

我暈看了好久,別人寫的代碼看的真是辛苦,也沒注釋...修改了一堆括號(hào)!!

妥妥的沒問題,你的資源用的數(shù)組,換句話說(shuō),

你數(shù)組被A1線程增加索引1,然后B過(guò)來(lái)拿走索引1;?數(shù)組里面此刻是什么?當(dāng)然是0了啊;因?yàn)槟氵f減了...

然后A2被拿到執(zhí)行權(quán),怎么樣?是不是還去增加索引1??明白了?

如果你想要不重復(fù),就別遞減就行了!

另外你這么改,有什么問題看的很醒目,知道發(fā)生在哪個(gè)線程上!

JAVA怎么編多個(gè)生產(chǎn)者多個(gè)消費(fèi)者代碼啊

public?class?ProduceConsumerDemo?{

public?static?void?main(String[]?args)?{

//?1.創(chuàng)建資源

Resource?resource?=?new?Resource();

//?2.創(chuàng)建兩個(gè)任務(wù)

Producer?producer?=?new?Producer(resource);

Consumer?consumer?=?new?Consumer(resource);

//?3.創(chuàng)建線程

/*

*?多生產(chǎn)多消費(fèi)產(chǎn)生的問題:重復(fù)生產(chǎn)、重復(fù)消費(fèi)

*/

Thread?thread0?=?new?Thread(producer);

Thread?thread1?=?new?Thread(producer);

thread0.setName("生產(chǎn)者(NO0)");

thread1.setName("生產(chǎn)者(NO1)");

Thread?thread2?=?new?Thread(consumer);

Thread?thread3?=?new?Thread(consumer);

thread2.setName("消費(fèi)者(NO2)");

thread3.setName("消費(fèi)者(NO3)");

thread0.start();

thread1.start();

thread2.start();

thread3.start();

}

}

class?Resource?{

private?String?name;

private?int?count?=?1;

//?定義標(biāo)記

private?boolean?flag;

//?提供給商品賦值的方法

public?synchronized?void?setName(String?name)?{//?thread0,?thread1在這里運(yùn)行

while?(flag)//?判斷標(biāo)記為true,執(zhí)行wait等待,為false則生產(chǎn)

/*

*?這里使用while,而不使用if的理由如下:

*?

*?thread0有可能第二次也搶到鎖的執(zhí)行權(quán),判斷為真,則有面包不生產(chǎn),所以接下來(lái)執(zhí)行等待,此時(shí)thread0在線程池中。

*?接下來(lái)活的線程有3個(gè)(除了thread0),這三個(gè)線程都有可能獲取到執(zhí)行權(quán).

*?假設(shè)thread1獲得了執(zhí)行權(quán),判斷為真,則有面包不生產(chǎn),執(zhí)行等待。此時(shí)thread1又進(jìn)入到了線程池中。

*?接下來(lái)有兩個(gè)活的線程thread2和thread3。?假設(shè)thread2又搶到了執(zhí)行權(quán),所以程序轉(zhuǎn)到了消費(fèi)get處……

*/

try?{

this.wait();//這里wait語(yǔ)句必須包含在try/catch塊中,拋出異常。

}?catch?(InterruptedException?e)?{

e.printStackTrace();

}

this.name?=?name?+?count;//?第一個(gè)面包

count++;//?2

System.out.println(Thread.currentThread().getName()?+?this.name);//?thread0線程生產(chǎn)了面包1

//?生產(chǎn)完畢,將標(biāo)記改成true.

flag?=?true;//?thread0第一次生產(chǎn)完面包以后,將標(biāo)記改為真,表示有面包了

//?喚醒消費(fèi)者(這里使用notifyAll而不使用notify的原因在下面)

this.notifyAll();//?第一次在這里是空喚醒,沒有意義

}

/*

*?通過(guò)同步,解決了沒生產(chǎn)就消費(fèi)的問題

*?生產(chǎn)完以后,生產(chǎn)者釋放了this鎖,此時(shí),生產(chǎn)者和消費(fèi)者同時(shí)去搶鎖,又是生產(chǎn)者搶到了鎖,所以就出現(xiàn)了一直生產(chǎn)的情況。

*?與“生產(chǎn)一個(gè)就消費(fèi)一個(gè)的需求不符合”?等待喚醒機(jī)制?wait();該方法可以使線程處于凍結(jié)狀態(tài),并將線程臨時(shí)存儲(chǔ)到線程池

*?notify();喚醒指定線程池中的任意一個(gè)線程。?notifyAll();喚醒指定線程池中的所有線程

*?這些方法必須使用在同步函數(shù)中,因?yàn)樗麄冇脕?lái)操作同步鎖上的線程上的狀態(tài)的。

*?在使用這些方法時(shí)候,必須標(biāo)識(shí)他們所屬于的鎖,標(biāo)識(shí)方式就是鎖對(duì)象.wait();?鎖對(duì)象.notify();?鎖對(duì)象.notifyAll();

*?相同鎖的notify()可以獲取相同鎖的wait();

*/

public?synchronized?void?getName()?{//?thread2,thread3在這里運(yùn)行

while?(!flag)

/*

*?……接著上面的程序執(zhí)行分析?thread2拿到鎖獲取執(zhí)行權(quán)之后,判斷!flag為假,則不等待,直接消費(fèi)面包1,輸出一次.

*?消費(fèi)完成之后將flag改為假?接下來(lái)又喚醒了thread0或者thread1生產(chǎn)者中的一個(gè)

*?假設(shè)又喚醒了thread0線程,現(xiàn)在活的線程有thread0,thread2,thread3三個(gè)線程

*?假設(shè)接下來(lái)thread2又搶到了執(zhí)行權(quán),判斷!flag為真,沒面包了,停止消費(fèi),所以thread2執(zhí)行等待.

*?此時(shí)活著的線程有thread0和thread3。

*?假設(shè)thread3得到了執(zhí)行權(quán),拿到鎖之后進(jìn)來(lái)執(zhí)行等待,此時(shí)活著的線程只有thread0.

*?所以thread0只能搶到執(zhí)行權(quán)之后,生產(chǎn)面包2,將標(biāo)記改為true告訴消費(fèi)者有面包可以消費(fèi)了。

*?接下來(lái)執(zhí)行notify喚醒,此時(shí)喚醒休眠中的3個(gè)線程中的任何一個(gè)都有可能。

*?如果喚醒了消費(fèi)者thread2或者thread3中的任何一個(gè),程序都是正常。如果此時(shí)喚醒thread1則不正常。

*?如果喚醒了thread1,此時(shí)活著的線程有thread0和thread1兩個(gè)線程。

*?假設(shè)thread0又獲得了執(zhí)行權(quán),判讀為真有面包,則又一次執(zhí)行等待。

*?接下來(lái)只有thread1線程有執(zhí)行權(quán)(此時(shí)沒有判斷標(biāo)記直接生產(chǎn)了,出錯(cuò)了),所以又生產(chǎn)了面包3。?在這個(gè)過(guò)程中,面包2沒有被消費(fèi)。

*?這就是連續(xù)生產(chǎn)和消費(fèi)容易出現(xiàn)的問題。

*?

*?原因:被喚醒的線程沒有判斷標(biāo)記就開始執(zhí)行了,導(dǎo)致了重復(fù)的生產(chǎn)和消費(fèi)發(fā)生。

*?

*?解決:被喚醒的線程必須判斷標(biāo)記,使用while循環(huán)標(biāo)記,而不使用if判斷的理由。

*?

*?但是接下來(lái)會(huì)出現(xiàn)死鎖,原因在于:

*?上面的程序中thread0在執(zhí)行notify的時(shí)候喚醒了thread1,而此時(shí)thread2和thread3兩個(gè)消費(fèi)者線程都處于等待狀態(tài)

*?thread1在執(zhí)行while判斷語(yǔ)句之后判斷為真,則執(zhí)行等待,此時(shí)所有的線程都處于凍結(jié)等待狀態(tài)了。

*?

*?原因:本方線程在執(zhí)行喚醒的時(shí)候又一次喚醒了本方線程,而本方線程循環(huán)判斷標(biāo)記又繼續(xù)等待,而導(dǎo)致所有的線程都等待。

*?

*?解決:本方線程喚醒對(duì)方線程,?可以使用notifyAll()方法

*? 喚醒之后,既有本方,又有對(duì)方,但是本方線程判斷標(biāo)記之后,會(huì)繼續(xù)等待,這樣就有對(duì)方線程在執(zhí)行。

*/

try?{

this.wait();

}?catch?(InterruptedException?e)?{

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()??+?this.name);

//?將標(biāo)記改為false

flag?=?false;

//?喚醒生產(chǎn)者

this.notify();

}

}

//?生產(chǎn)者

class?Producer?implements?Runnable?{

private?Resource?resource;

public?Producer(Resource?resource)?{

this.resource?=?resource;

}

public?void?run()?{

while?(true)?{

resource.setName("面包");

}

}

}

//?消費(fèi)者

class?Consumer?implements?Runnable?{

private?Resource?resource;

public?Consumer(Resource?resource)?{

this.resource?=?resource;

}

@Override

public?void?run()?{

while?(true)?{

resource.getName();

}

}

}

Java 生產(chǎn)者,消費(fèi)者代碼中,如果使用if和notify()函數(shù),其中生產(chǎn)者兩個(gè)線程,消費(fèi)者一

線程的運(yùn)行時(shí)隨機(jī)的,它不是交替運(yùn)行的,如果只有這兩個(gè)線程的話,每次運(yùn)行都會(huì)進(jìn)行一個(gè)二選一的選擇.

你參考一下

public class ThreadABC extends Thread{

int i=0;

private static int count=0;

private static Object o=new Object();

public ThreadABC(String ID){

currentThread().setName(ID);

}

public void run() {

synchronized (o) {

while(true){

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

if(count%2==0currentThread().getName().equals("A")){

o.notify();

System.out.print(currentThread().getName());

count++;

try {

o.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

else if (count%2==1currentThread().getName().equals("B")) {

o.notify();

System.out.print(currentThread().getName());

count++;

try {

o.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

}

public static void main(String[] args) {

ThreadABC b=new ThreadABC("B");

ThreadABC a=new ThreadABC("A");

a.setName("A");

b.setName("B");

a.start();

b.start();

}

}

網(wǎng)站欄目:java生產(chǎn)消費(fèi)者代碼 java生產(chǎn)消費(fèi)者代碼是多少
分享鏈接:http://jinyejixie.com/article46/dodoehg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、建站公司、營(yíng)銷型網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣關(guān)鍵詞優(yōu)化、外貿(mào)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
郎溪县| 昌乐县| 大洼县| 翼城县| 蕉岭县| 绥德县| 子长县| 大竹县| 潢川县| 昌宁县| 英德市| 新民市| 徐水县| 开阳县| 罗平县| 分宜县| 吉林省| 翁牛特旗| 盱眙县| 大同县| 稻城县| 巩义市| 吴桥县| 仁化县| 尉犁县| 济宁市| 靖边县| 涞源县| 东光县| 永和县| 方山县| 五河县| 内丘县| 商都县| 广宗县| 汪清县| 大安市| 泾源县| 伽师县| 鹤峰县| 沛县|