rl 相當(dāng)于 一個(gè)生產(chǎn)者的倉庫(消費(fèi)者消費(fèi)的時(shí)候會(huì)從這個(gè)倉庫中拿東西);
創(chuàng)新互聯(lián)是一家專業(yè)提供陜州企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、html5、小程序制作等業(yè)務(wù)。10年已為陜州眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。
wp 相當(dāng)于庫存數(shù)量,生產(chǎn)者生產(chǎn)一次 wp數(shù)量會(huì)+1, 消費(fèi)者消費(fèi)一次 wp數(shù)量會(huì)-1
開啟線程:同步進(jìn)行生產(chǎn)跟消費(fèi)的動(dòng)作。(一個(gè)只生產(chǎn),一個(gè)只消費(fèi))
兩個(gè)方法(shengchan xiaofei) 是互相notify的,因?yàn)樗麄兊膚ait對(duì)象都是 Ck,所以理論上不會(huì)存在wait后不釋放的情況。可以再完善一下,用 reentrantLock 或者自己寫一個(gè)方法,比如在wait后幾秒 如果還未被notify 強(qiáng)制notify。
小小回顧 寫了個(gè)簡(jiǎn)單的demo 項(xiàng)目中沒有過 還能記得 紀(jì)念一下
產(chǎn)品的entity
Java代碼
public class Product {
//產(chǎn)品名稱
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this name = name;
}
}
生產(chǎn)者
Java代碼
/**
* 生產(chǎn)者
* @author 飯香
*
*/
public class Producer implements Runnable{
private Shop shop;//要去送貨的商店
public Producer(Shop shop){
this shop=shop;
}
public void run() {
for(int i= ;i ;i++){
shop produ();
}
}
}
消費(fèi)者
Java代碼
/**
* 消費(fèi)者
* @author 飯香
*
*/
public class Cousumer implements Runnable{
private Shop shop;//要去消費(fèi)的商店
public Cousumer(Shop shop){
this shop=shop;
}
public void run() {
for(int i= ;i ;i++){//消費(fèi) 次
usu();
}
}
}
模擬商店(一切圍繞商店 商店只能有一個(gè) 產(chǎn)品隨便多個(gè)實(shí)例 這個(gè)也是別人問我總是出錯(cuò)的地方 對(duì)象思想)
Java代碼
import java util ArrayList;
import java util List;
/**
* 模擬商店 (進(jìn)貨/銷售)
* @author fx
*
*/
public class Shop {
private static int i= ;
//產(chǎn)品的容器;達(dá)到容器暫停生產(chǎn) 消費(fèi)到 等待生產(chǎn)
private static ListProduct list;
static{
list= new ArrayListProduct();
}
/**
* 生產(chǎn)產(chǎn)品
*/
public synchronized void produ(){
if(list size()= ){
try {
System out println( 生產(chǎn)商品 +i+ 時(shí) 達(dá)到了總數(shù)暫停生產(chǎn) );
this wait();//進(jìn)入休眠
} catch (InterruptedException e) {
System out println(e toString());
e=null;
}
} //生產(chǎn)商品
Product product= new Product();
product setName( 商品 +i);
list add(product);
System out println( 生產(chǎn)了商品 +product getName()+ 商品總數(shù) +i);
System out println( 容器容量 +list size());
i++;
super notify();
}
/**
* 消費(fèi)產(chǎn)品
* @return
*/
public synchronized void cousu(){
if(list size()== ){//消費(fèi)完時(shí) 掛起
System out println( +++++++++++++++++++++++商品消費(fèi)完了 等待+++++++++++++++= );
try {
this wait();
} catch (InterruptedException e) {
// TODO Auto generated catch block
System out println(e toString());
e=null;
}
}
Product product=list get( );
list remove( );
System out println( 消費(fèi)了獲得了商品 +product getName());
System out println( 容器容量 +list size());
super notify();
}
}
測(cè)試代碼
Java代碼
public static void main(String[] args) {
Shop shop=new Shop();//商店
Producer pro=new Producer(shop);
Cousumer cou = new Cousumer(shop);
new Thread(pro pro ) start();
new Thread(cou cou ) start();
}
生產(chǎn)了商品 商品 商品總數(shù)
容器容量
消費(fèi)了獲得了商品 商品
容器容量
+++++++++++++++++++++++商品消費(fèi)完了 等待+++++++++++++++=
生產(chǎn)了商品 商品 商品總數(shù)
容器容量
消費(fèi)了獲得了商品 商品
容器容量
+++++++++++++++++++++++商品消費(fèi)完了 等待+++++++++++++++=
生產(chǎn)了商品 商品 商品總數(shù)
容器容量
消費(fèi)了獲得了商品 商品
容器容量
+++++++++++++++++++++++商品消費(fèi)完了 等待+++++++++++++++=
生產(chǎn)了商品 商品 商品總數(shù)
容器容量
生產(chǎn)了商品 商品 商品總數(shù)
容器容量
消費(fèi)了獲得了商品 商品
容器容量
生產(chǎn)了商品 商品 商品總數(shù)
容器容量
消費(fèi)了獲得了商品 商品
容器容量
生產(chǎn)了商品 商品 商品總數(shù)
容器容量
消費(fèi)了獲得了商品 商品
容器容量
消費(fèi)了獲得了商品 商品
lishixinzhi/Article/program/Java/gj/201311/27600
我暈看了好久,別人寫的代碼看的真是辛苦,也沒注釋...修改了一堆括號(hào)!!
妥妥的沒問題,你的資源用的數(shù)組,換句話說,
你數(shù)組被A1線程增加索引1,然后B過來拿走索引1;?數(shù)組里面此刻是什么?當(dāng)然是0了啊;因?yàn)槟氵f減了...
然后A2被拿到執(zhí)行權(quán),怎么樣?是不是還去增加索引1??明白了?
如果你想要不重復(fù),就別遞減就行了!
另外你這么改,有什么問題看的很醒目,知道發(fā)生在哪個(gè)線程上!
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),所以接下來執(zhí)行等待,此時(shí)thread0在線程池中。
*?接下來活的線程有3個(gè)(除了thread0),這三個(gè)線程都有可能獲取到執(zhí)行權(quán).
*?假設(shè)thread1獲得了執(zhí)行權(quán),判斷為真,則有面包不生產(chǎn),執(zhí)行等待。此時(shí)thread1又進(jìn)入到了線程池中。
*?接下來有兩個(gè)活的線程thread2和thread3。?假設(shè)thread2又搶到了執(zhí)行權(quán),所以程序轉(zhuǎn)到了消費(fèi)get處……
*/
try?{
this.wait();//這里wait語句必須包含在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();//?第一次在這里是空喚醒,沒有意義
}
/*
*?通過同步,解決了沒生產(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)樗麄冇脕聿僮魍芥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改為假?接下來又喚醒了thread0或者thread1生產(chǎn)者中的一個(gè)
*?假設(shè)又喚醒了thread0線程,現(xiàn)在活的線程有thread0,thread2,thread3三個(gè)線程
*?假設(shè)接下來thread2又搶到了執(zhí)行權(quán),判斷!flag為真,沒面包了,停止消費(fèi),所以thread2執(zhí)行等待.
*?此時(shí)活著的線程有thread0和thread3。
*?假設(shè)thread3得到了執(zhí)行權(quán),拿到鎖之后進(jìn)來執(zhí)行等待,此時(shí)活著的線程只有thread0.
*?所以thread0只能搶到執(zhí)行權(quán)之后,生產(chǎn)面包2,將標(biāo)記改為true告訴消費(fèi)者有面包可以消費(fè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í)行等待。
*?接下來只有thread1線程有執(zhí)行權(quán)(此時(shí)沒有判斷標(biāo)記直接生產(chǎn)了,出錯(cuò)了),所以又生產(chǎn)了面包3。?在這個(gè)過程中,面包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判斷的理由。
*?
*?但是接下來會(huì)出現(xiàn)死鎖,原因在于:
*?上面的程序中thread0在執(zhí)行notify的時(shí)候喚醒了thread1,而此時(shí)thread2和thread3兩個(gè)消費(fèi)者線程都處于等待狀態(tài)
*?thread1在執(zhí)行while判斷語句之后判斷為真,則執(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();
}
}
}
public static void main(String[] args) {
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)容寫入
使用的生產(chǎn)者和消費(fèi)者模型具有如下特點(diǎn):
(1)本實(shí)驗(yàn)的多個(gè)緩沖區(qū)不是環(huán)形循環(huá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ù)滿足了所有關(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)過程結(jié)束時(shí)需要判斷該消費(fèi)對(duì)象是否已經(jīng)消費(fèi)完畢并清除該產(chǎn)品。
Windows
用來實(shí)現(xiàn)同步和互斥的實(shí)體。在Windows
中,常見的同步對(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è)線程中創(chuàng)建,在其他線程
中都可以使用,從而實(shí)現(xiàn)同步互斥。當(dāng)然,在進(jìn)程間使用這些同步對(duì)象實(shí)現(xiàn)同步的方法是類似的。
1.用鎖操作原語實(shí)現(xiàn)互斥
為解決進(jìn)程互斥進(jìn)人臨界區(qū)的問題,可為每類臨界區(qū)設(shè)置一把鎖,該鎖有打開和關(guān)閉兩種狀態(tài),進(jìn)程執(zhí)行臨界區(qū)程序的操作按下列步驟進(jìn)行:
①關(guān)鎖。先檢查鎖的狀態(tài),如為關(guān)閉狀態(tài),則等待其打開;如已打開了,則將其關(guān)閉,繼續(xù)執(zhí)行步驟②的操作。
②執(zhí)行臨界區(qū)程序。
③開鎖。將鎖打開,退出臨界區(qū)。
2.信號(hào)量及WAIT,SIGNAL操作原語
信號(hào)量的初值可以由系統(tǒng)根據(jù)資源情況和使用需要來確定。在初始條件下信號(hào)量的指針項(xiàng)可以置為0,表示隊(duì)列為空。信號(hào)量在使用過程中它的值是可變的,但只能由WAIT,SIGNAL操作來改變。設(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操作,把它釋放出來為止)。
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í)行。也就是說,WAIT,SIGNAL操作各自都好像對(duì)應(yīng)一條指令,需要不間斷地做下去,否則會(huì)造成混亂。
從物理概念上講,信號(hào)量S)時(shí),S值表示可用資源的數(shù)量。執(zhí)行一次WAIT操作意味著請(qǐng)求分配一個(gè)單位資源,因此S值減1;當(dāng)S0時(shí),表示已無可用資源,請(qǐng)求者必須等待別的進(jìn)程釋放了該類資源,它才能運(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;
}
-----------------
/**
*
此類用來模擬信號(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();
}
}
--------------------------------------------
本文標(biāo)題:java生產(chǎn)消費(fèi)代碼 編程實(shí)現(xiàn)生產(chǎn)者消費(fèi)者問題java
新聞來源:http://chinadenli.net/article40/hgdseo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、動(dòng)態(tài)網(wǎng)站、網(wǎng)站策劃、品牌網(wǎng)站設(shè)計(jì)、商城網(wǎng)站、外貿(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í)需注明來源: 創(chuàng)新互聯(lián)