真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

生產(chǎn)者消費(fèi)者代碼java 生產(chǎn)者消費(fèi)者代碼分析

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

public static void main(String[] args) {

在姚安等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專(zhuān)注、極致的服務(wù)理念,為客戶(hù)提供網(wǎng)站制作、成都做網(wǎng)站 網(wǎng)站設(shè)計(jì)制作按需求定制開(kāi)發(fā),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),成都營(yíng)銷(xiāo)網(wǎng)站建設(shè),外貿(mào)網(wǎng)站建設(shè),姚安網(wǎng)站建設(shè)費(fèi)用合理。

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

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

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

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

}

這一段代碼,多加入

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

多加一段代碼創(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)同步的主要緩存類(lèi)。想要實(shí)現(xiàn)同步

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

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

就比如

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

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

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

妥妥的沒(méi)問(wèn)題,你的資源用的數(shù)組,換句話(huà)說(shuō),

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

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

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

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

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)建線(xiàn)程

/*

*?多生產(chǎn)多消費(fèi)產(chǎn)生的問(wè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在線(xiàn)程池中。

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

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

*?接下來(lái)有兩個(gè)活的線(xiàn)程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線(xiàn)程生產(chǎn)了面包1

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

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

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

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

}

/*

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

*?生產(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();該方法可以使線(xiàn)程處于凍結(jié)狀態(tài),并將線(xiàn)程臨時(shí)存儲(chǔ)到線(xiàn)程池

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

*?這些方法必須使用在同步函數(shù)中,因?yàn)樗麄冇脕?lái)操作同步鎖上的線(xiàn)程上的狀態(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)程,現(xiàn)在活的線(xiàn)程有thread0,thread2,thread3三個(gè)線(xiàn)程

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

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

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

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

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

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

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

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

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

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

*?

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

*?

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

*?

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

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

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

*?

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

*?

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

*? 喚醒之后,既有本方,又有對(duì)方,但是本方線(xiàn)程判斷標(biāo)記之后,會(huì)繼續(xù)等待,這樣就有對(duì)方線(xiàn)程在執(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中關(guān)于消費(fèi)者和生產(chǎn)者的問(wèn)題?

public?class?ProducerConsumer_3

{

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

{

SyncStack?ss?=?new?SyncStack();

Producer?p?=?new?Producer(ss);

Consumer?c?=?new?Consumer(ss);

Thread?t1?=?new?Thread(p);

Thread?t2?=?new?Thread(c);

t1.start();

t2.start();

}

}

class?SyncStack

{

int?cnt?=?0;

char[]?data?=?new?char[6];

public?synchronized?void?push(char?ch)

{

while?(cnt?==?data.length)

{

try

{

this.wait(); //wait是Object?類(lèi)中的方法,不是Thread中的方法,Thread中wait也是繼承自O(shè)bject,??????

???//this.wait();不是讓當(dāng)前對(duì)象wait,而是讓當(dāng)前鎖定this對(duì)象的線(xiàn)程wait,同時(shí)釋放對(duì)this的鎖定。

??//注意:如果該對(duì)象沒(méi)有被鎖定,則調(diào)用wait方法就會(huì)報(bào)錯(cuò)!即只有在同步方法或者同步代碼塊中才可以調(diào)用wait方法,notify同理

}

catch?(Exception?e)

{

}

}

this.notify();??//如果注釋掉了本語(yǔ)句,可能會(huì)導(dǎo)致消費(fèi)線(xiàn)程陷入阻塞(如果消費(fèi)線(xiàn)程本身執(zhí)行很慢的話(huà),則消費(fèi)線(xiàn)程永遠(yuǎn)不會(huì)wait,即永遠(yuǎn)不會(huì)阻塞),因?yàn)橄M(fèi)線(xiàn)程陷入阻塞,?所以生產(chǎn)線(xiàn)程因此不停生產(chǎn)產(chǎn)品達(dá)到6個(gè)后也陷入阻塞,最后顯示的肯定是“容器中現(xiàn)在共有6個(gè)字符!”

//this.notify();叫醒一個(gè)現(xiàn)在正在wait??this對(duì)象的一個(gè)線(xiàn)程,如果有多個(gè)線(xiàn)程正在wait?this對(duì)象,通常是叫醒最先wait?this對(duì)象的線(xiàn)程,但具體是叫醒哪一個(gè),這是由系統(tǒng)調(diào)度器控制,程序員無(wú)法控制?

//?nority?和?notifyAll?都是Object?類(lèi)中的方法

data[cnt]?=?ch;

cnt++;

System.out.printf("生產(chǎn)了:?%c\n",?ch);

System.out.printf("容器中現(xiàn)在共有%d個(gè)字符!\n\n",?cnt);

}

public?synchronized?char?pop()

{

char?ch;

while?(0?==?cnt)

{

try

{

this.wait();

}

catch?(Exception?e)

{

}

}

this.notify();??//如果注釋掉了本語(yǔ)句,可能會(huì)導(dǎo)致生產(chǎn)線(xiàn)程陷入阻塞(如果生產(chǎn)線(xiàn)程本身執(zhí)行很慢的話(huà),則生產(chǎn)線(xiàn)程永遠(yuǎn)不會(huì)wait,即永遠(yuǎn)不會(huì)阻塞),因?yàn)樯a(chǎn)線(xiàn)程陷入阻塞,消費(fèi)線(xiàn)程因此不停取出產(chǎn)品,當(dāng)容器中再也沒(méi)有產(chǎn)品時(shí)消費(fèi)線(xiàn)程也陷入阻塞,最后顯示的肯定是“容器中現(xiàn)在共有0個(gè)字符!”

ch?=?data[cnt-1];

--cnt;

System.out.printf("取出:??%c\n",?ch);

System.out.printf("容器中現(xiàn)在共有%d個(gè)字符!\n\n",?cnt);

return?ch;

}

}

class?Producer?implements?Runnable

{

SyncStack?ss?=?null;

public?Producer(SyncStack?ss)

{

this.ss?=?ss;

}

public?void?run()

{

char?ch;

//總共生產(chǎn)20個(gè)產(chǎn)品

for?(int?i=0;?i20;?++i)

{

ch?=?(char)('a'+i);

ss.push(ch);

// try

// {

// Thread.sleep(500);

// }

// catch?(Exception?e)

// {

// }

}

}

}

class?Consumer?implements?Runnable

{

SyncStack?ss?=?null;

public?Consumer(SyncStack?ss)

{

this.ss?=?ss;

}

//總共消費(fèi)20個(gè)產(chǎn)品

public?void?run()

{

for?(int?i=0;?i20;?++i)

{

ss.pop();

try

{

Thread.sleep(500);

}

catch?(Exception?e)

{

}

}

}

}

java實(shí)現(xiàn)生產(chǎn)者和消費(fèi)者問(wèn)題的幾種方式

生產(chǎn)者消費(fèi)者問(wèn)題是多線(xiàn)程的一個(gè)經(jīng)典問(wèn)題,它描述是有一塊緩沖區(qū)作為倉(cāng)庫(kù),生產(chǎn)者可以將產(chǎn)品放入倉(cāng)庫(kù),消費(fèi)者則可以從倉(cāng)庫(kù)中取走產(chǎn)品。

解決生產(chǎn)者/消費(fèi)者問(wèn)題的方法可分為兩類(lèi):

采用某種機(jī)制保護(hù)生產(chǎn)者和消費(fèi)者之間的同步;

在生產(chǎn)者和消費(fèi)者之間建立一個(gè)管道。

第一種方式有較高的效率,并且易于實(shí)現(xiàn),代碼的可控制性較好,屬于常用的模式。第二種管道緩沖區(qū)不易控制,被傳輸數(shù)據(jù)對(duì)象不易于封裝等,實(shí)用性不強(qiáng)。

在Java中有四種方法支持同步,其中前三個(gè)是同步方法,一個(gè)是管道方法。

wait()

/

notify()方法

await()

/

signal()方法

BlockingQueue阻塞隊(duì)列方法

PipedInputStream

/

PipedOutputStream

通過(guò)

wait()

/

notify()方法實(shí)現(xiàn):

wait()

/

nofity()方法是基類(lèi)Object的兩個(gè)方法:

wait()方法:當(dāng)緩沖區(qū)已滿(mǎn)/空時(shí),生產(chǎn)者/消費(fèi)者線(xiàn)程停止自己的執(zhí)行,放棄鎖,使自己處于等等狀態(tài),讓其他線(xiàn)程執(zhí)行。

notify()方法:當(dāng)生產(chǎn)者/消費(fèi)者向緩沖區(qū)放入/取出一個(gè)產(chǎn)品時(shí),向其他等待的線(xiàn)程發(fā)出可執(zhí)行的通知,同時(shí)放棄鎖,使自己處于等待狀態(tài)。

通過(guò)await()

/

signal()方法實(shí)現(xiàn):

await()和signal()的功能基本上和wait()

/

nofity()相同,完全可以取代它們,但是它們和新引入的鎖定機(jī)制Lock直接掛鉤,具有更大的靈活性。通過(guò)在Lock對(duì)象上調(diào)用newCondition()方法,將條件變量和一個(gè)鎖對(duì)象進(jìn)行綁定,進(jìn)而控制并發(fā)程序訪問(wèn)競(jìng)爭(zhēng)資源的安全。

通過(guò)BlockingQueue方法實(shí)現(xiàn):

它是一個(gè)已經(jīng)在內(nèi)部實(shí)現(xiàn)了同步的隊(duì)列,實(shí)現(xiàn)方式采用的是我們第2種await()

/

signal()方法。它可以在生成對(duì)象時(shí)指定容量大小。它用于阻塞操作的是put()和take()方法:

put()方法:類(lèi)似于我們上面的生產(chǎn)者線(xiàn)程,容量達(dá)到最大時(shí),自動(dòng)阻塞。

take()方法:類(lèi)似于我們上面的消費(fèi)者線(xiàn)程,容量為0時(shí),自動(dòng)阻塞。

JAVA模擬生產(chǎn)者與消費(fèi)者實(shí)例

使用的生產(chǎn)者和消費(fèi)者模型具有如下特點(diǎn):

(1)本實(shí)驗(yàn)的多個(gè)緩沖區(qū)不是環(huán)形循環(huán)的,也不要求按順序訪問(wèn)。生產(chǎn)者可以把產(chǎn)品放到目前某一個(gè)空緩沖區(qū)中。

(2)消費(fèi)者只消費(fèi)指定生產(chǎn)者的產(chǎn)品。

(3)在測(cè)試用例文件中指定了所有的生產(chǎn)和消費(fèi)的需求,只有當(dāng)共享緩沖區(qū)的數(shù)據(jù)滿(mǎn)足了所有關(guān)于它的消費(fèi)需求后,此共享緩沖區(qū)才可以作為空閑空間允許新的生產(chǎn)者使用。

(4)本實(shí)驗(yàn)在為生產(chǎn)者分配緩沖區(qū)時(shí)各生產(chǎn)者間必須互斥,此后各個(gè)生產(chǎn)者的具體生產(chǎn)活動(dòng)可以并發(fā)。而消費(fèi)者之間只有在對(duì)同一產(chǎn)品進(jìn)行消費(fèi)時(shí)才需要互斥,同時(shí)它們?cè)谙M(fèi)過(guò)程結(jié)束時(shí)需要判斷該消費(fèi)對(duì)象是否已經(jīng)消費(fèi)完畢并清除該產(chǎn)品。

Windows

用來(lái)實(shí)現(xiàn)同步和互斥的實(shí)體。在Windows

中,常見(jiàn)的同步對(duì)象有:信號(hào)量(Semaphore)、

互斥量(Mutex)、臨界段(CriticalSection)和事件(Event)等。本程序中用到了前三個(gè)。使用這些對(duì)象都分

為三個(gè)步驟,一是創(chuàng)建或者初始化:接著請(qǐng)求該同步對(duì)象,隨即進(jìn)入臨界區(qū),這一步對(duì)應(yīng)于互斥量的

上鎖;最后釋放該同步對(duì)象,這對(duì)應(yīng)于互斥量的解鎖。這些同步對(duì)象在一個(gè)線(xiàn)程中創(chuàng)建,在其他線(xiàn)程

中都可以使用,從而實(shí)現(xiàn)同步互斥。當(dāng)然,在進(jìn)程間使用這些同步對(duì)象實(shí)現(xiàn)同步的方法是類(lèi)似的。

1.用鎖操作原語(yǔ)實(shí)現(xiàn)互斥

為解決進(jìn)程互斥進(jìn)人臨界區(qū)的問(wèn)題,可為每類(lèi)臨界區(qū)設(shè)置一把鎖,該鎖有打開(kāi)和關(guān)閉兩種狀態(tài),進(jìn)程執(zhí)行臨界區(qū)程序的操作按下列步驟進(jìn)行:

①關(guān)鎖。先檢查鎖的狀態(tài),如為關(guān)閉狀態(tài),則等待其打開(kāi);如已打開(kāi)了,則將其關(guān)閉,繼續(xù)執(zhí)行步驟②的操作。

②執(zhí)行臨界區(qū)程序。

③開(kāi)鎖。將鎖打開(kāi),退出臨界區(qū)。

2.信號(hào)量及WAIT,SIGNAL操作原語(yǔ)

信號(hào)量的初值可以由系統(tǒng)根據(jù)資源情況和使用需要來(lái)確定。在初始條件下信號(hào)量的指針項(xiàng)可以置為0,表示隊(duì)列為空。信號(hào)量在使用過(guò)程中它的值是可變的,但只能由WAIT,SIGNAL操作來(lái)改變。設(shè)信號(hào)量為S,對(duì)S的WAIT操作記為WAIT(S),對(duì)它的SIGNAL操作記為SIGNAL(S)。

WAIT(S):順序執(zhí)行以下兩個(gè)動(dòng)作:

①信號(hào)量的值減1,即S=S-1;

②如果S≥0,則該進(jìn)程繼續(xù)執(zhí)行;

如果

S(0,則把該進(jìn)程的狀態(tài)置為阻塞態(tài),把相應(yīng)的WAITCB連人該信號(hào)量隊(duì)列的末尾,并放棄處理機(jī),進(jìn)行等待(直至其它進(jìn)程在S上執(zhí)行SIGNAL操作,把它釋放出來(lái)為止)。

SIGNAL(S):順序執(zhí)行以下兩個(gè)動(dòng)作

①S值加

1,即

S=S+1;

②如果S)0,則該進(jìn)程繼續(xù)運(yùn)行;

如果S(0則釋放信號(hào)量隊(duì)列上的第一個(gè)PCB(既信號(hào)量指針項(xiàng)所指向的PCB)所對(duì)應(yīng)的進(jìn)程(把阻塞態(tài)改為就緒態(tài)),執(zhí)行SIGNAL操作的進(jìn)程繼續(xù)運(yùn)行。

在具體實(shí)現(xiàn)時(shí)注意,WAIT,SIGNAL操作都應(yīng)作為一個(gè)整體實(shí)施,不允許分割或相互穿插執(zhí)行。也就是說(shuō),WAIT,SIGNAL操作各自都好像對(duì)應(yīng)一條指令,需要不間斷地做下去,否則會(huì)造成混亂。

從物理概念上講,信號(hào)量S)時(shí),S值表示可用資源的數(shù)量。執(zhí)行一次WAIT操作意味著請(qǐng)求分配一個(gè)單位資源,因此S值減1;當(dāng)S0時(shí),表示已無(wú)可用資源,請(qǐng)求者必須等待別的進(jìn)程釋放了該類(lèi)資源,它才能運(yùn)行下去。所以它要排隊(duì)。而執(zhí)行一次SIGNAL操作意味著釋放一個(gè)單位資源,因此S值加1;若S(0時(shí),表示有某些進(jìn)程正在等待該資源,因而要把隊(duì)列頭上的進(jìn)程喚醒,釋放資源的進(jìn)程總是可以運(yùn)行下去的。

---------------

/**

*

生產(chǎn)者

*

*/

public

class

Producer

implements

Runnable{

private

Semaphore

mutex,full,empty;

private

Buffer

buf;

String

name;

public

Producer(String

name,Semaphore

mutex,Semaphore

full,Semaphore

empty,Buffer

buf){

this.mutex

=

mutex;

this.full

=

full;

this.empty

=

empty;

this.buf

=

buf;

this.name

=

name;

}

public

void

run(){

while(true){

empty.p();

mutex.p();

System.out.println(name+"

inserts

a

new

product

into

"+buf.nextEmptyIndex);

buf.nextEmptyIndex

=

(buf.nextEmptyIndex+1)%buf.size;

mutex.v();

full.v();

try

{

Thread.sleep(1000);

}

catch

(InterruptedException

e)

{

e.printStackTrace();

}

}

}

}

---------------

/**

*

消費(fèi)者

*

*/

public

class

Customer

implements

Runnable{

private

Semaphore

mutex,full,empty;

private

Buffer

buf;

String

name;

public

Customer(String

name,Semaphore

mutex,Semaphore

full,Semaphore

empty,Buffer

buf){

this.mutex

=

mutex;

this.full

=

full;

this.empty

=

empty;

this.buf

=

buf;

this.name

=

name;

}

public

void

run(){

while(true){

full.p();

mutex.p();

System.out.println(name+"

gets

a

product

from

"+buf.nextFullIndex);

buf.nextFullIndex

=

(buf.nextFullIndex+1)%buf.size;

mutex.v();

empty.v();

try

{

Thread.sleep(1000);

}

catch

(InterruptedException

e)

{

e.printStackTrace();

}

}

}

}

-------------------------

/**

*

緩沖區(qū)

*

*/

public

class

Buffer{

public

Buffer(int

size,int

nextEmpty,int

nextFull){

this.nextEmptyIndex

=

nextEmpty;

this.nextFullIndex

=

nextFull;

this.size

=

size;

}

public

int

size;

public

int

nextEmptyIndex;

public

int

nextFullIndex;

}

-----------------

/**

*

此類(lèi)用來(lái)模擬信號(hào)量

*

*/

public

class

Semaphore{

private

int

semValue;

public

Semaphore(int

semValue){

this.semValue

=

semValue;

}

public

synchronized

void

p(){

semValue--;

if(semValue0){

try

{

this.wait();

}

catch

(InterruptedException

e)

{

e.printStackTrace();

}

}

}

public

synchronized

void

v(){

semValue++;

if(semValue=0){

this.notify();

}

}

}

------------------------

public

class

Test

extends

Thread

{

public

static

void

main(String[]

args)

{

Buffer

bf=new

Buffer(10,0,0);

Semaphore

mutex=new

Semaphore(1);

Semaphore

full=new

Semaphore(0);

Semaphore

empty=new

Semaphore(10);

//new

Thread(new

Producer("p001",mutex,full,empty,bf)).start();

Producer

p=new

Producer("p001",mutex,full,empty,bf);

new

Thread(new

Producer("p002",mutex,full,empty,bf)).start();

new

Thread(new

Producer("p003",mutex,full,empty,bf)).start();

new

Thread(new

Producer("p004",mutex,full,empty,bf)).start();

new

Thread(new

Producer("p005",mutex,full,empty,bf)).start();

try{

sleep(3000);

}

catch(Exception

ex)

{

ex.printStackTrace();

}

new

Thread(new

Customer("c001",mutex,full,empty,bf)).start();

new

Thread(new

Customer("c002",mutex,full,empty,bf)).start();

new

Thread(new

Customer("c003",mutex,full,empty,bf)).start();

new

Thread(new

Customer("c004",mutex,full,empty,bf)).start();

new

Thread(new

Customer("c005",mutex,full,empty,bf)).start();

}

}

--------------------------------------------


本文題目:生產(chǎn)者消費(fèi)者代碼java 生產(chǎn)者消費(fèi)者代碼分析
網(wǎng)頁(yè)URL:http://weahome.cn/article/hicojo.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部