JAVA 多線程經(jīng)典案例-生產(chǎn)者消費者模型【使用wait/notify實現(xiàn)】

生產(chǎn)者消費者模型實現(xiàn)細節(jié)

生產(chǎn)者生產(chǎn)產(chǎn)品到公共倉庫释移,消費者消費公共倉庫中產(chǎn)品。

情況一:當公共倉庫產(chǎn)品達到倉庫容量上限辽狈,生產(chǎn)者停止生產(chǎn)慈参;

情況二:當公共倉庫沒有產(chǎn)品,或達到設(shè)置的倉庫容量下限刮萌,消費者停止消費驮配;

情況三:當公共倉庫產(chǎn)品達到容量上限時,消費者消費一次,就可以讓生產(chǎn)者繼續(xù)生產(chǎn)壮锻;

情況四:當公共倉庫沒有產(chǎn)品時琐旁,生產(chǎn)者生產(chǎn)一次,就可以讓消費者繼續(xù)消費猜绣;

功能實現(xiàn)說明

公共倉庫 灰殴,包含“倉庫容量上限”、“倉庫容量下限”掰邢、“當前容量”基礎(chǔ)屬性验懊,及“入庫”、“出庫”基礎(chǔ)方法尸变;

生產(chǎn)者 义图,包含“所屬倉庫”、“每次生產(chǎn)數(shù)量”基礎(chǔ)屬性召烂,及“生產(chǎn)存入倉庫”基礎(chǔ)方法碱工;

消費者 ,包含“所屬倉庫”奏夫、“每次消費數(shù)量”基礎(chǔ)屬性怕篷,及“倉庫取出消費”基礎(chǔ)方法;

代碼實現(xiàn)

公共倉庫 酗昼,抽取“入庫”廊谓、“出庫”基礎(chǔ)方法作為接口,后續(xù)可通過實現(xiàn)該接口麻削,重寫方法來實現(xiàn)蒸痹;

(1)公共倉庫接口

/** *@date2018年12月11日 *@methodputIn(int num) //往倉庫中存入指定數(shù)量的產(chǎn)品 *@methodoutOf(int num) //從倉庫中取出制定數(shù)量的產(chǎn)品 */interfaceAbstractStorage{voidputIn(intnum);voidoutOf(intnum);}

(2)倉庫實現(xiàn)類

倉庫類只需判斷庫存量是否達到存入/取出閾值,從而限制生產(chǎn)者/消費者的存入/取出呛哟,不需要使用循環(huán)來判斷叠荠;

/** *@date2018年12月11日 *@paramMAX_PRODUCT //倉庫容量上限 *@paramMIN_PRODUCT //倉庫容量下限 *@paramstock //倉庫當前容量,屬于共享資源 *@methodputIn(int) //當(庫存+即將存入)大于容量上限扫责,停止存入 *@methodoutOf(int) //當(庫存-即將取出)小于容量上限榛鼎,停止取出 */classStorageimplementsAbstractStorage{publicfinalintMAX_PRODUCT =10;publicfinalintMIN_PRODUCT =0;privateintstock;@OverridepublicsynchronizedvoidputIn(intnum){if((stock + num) >= MAX_PRODUCT) {System.out.println("庫存已滿!");try{wait();}catch(InterruptedException e) {e.printStackTrace();}}else{stock += num;System.out.println(Thread.currentThread().getName() +"存入鳖孤,庫存:"+ stock);notifyAll();}}@OverridepublicsynchronizedvoidoutOf(intnum){if((stock - num) <= MIN_PRODUCT) {System.out.println("庫存已空者娱!");try{wait();}catch(InterruptedException e) {e.printStackTrace();}}else{stock -= num;System.out.println(Thread.currentThread().getName() +"取出,庫存:"+ stock);notifyAll();}}publicintgetStock(){returnstock;}publicvoidsetStock(intstock){this.stock = stock;}}

生產(chǎn)者

使用實現(xiàn)Runnable接口方式創(chuàng)建生產(chǎn)者線程苏揣,將生產(chǎn)者生產(chǎn)操作放到重寫的run()方法中黄鳍,實現(xiàn)生產(chǎn)者線程生產(chǎn);

/** *@Data2018年12月11日 *@paramstorage //公共倉庫 *@paramnum //生產(chǎn)數(shù)量 *@constructorProduce(AbstractStorage) //構(gòu)造器 *@methodprod(int) //生產(chǎn)者生產(chǎn)方法 *@methodrun() //生產(chǎn)者線程執(zhí)行方法 *@methodsetNum(int) //設(shè)置生產(chǎn)者每次生產(chǎn)數(shù)量 */classProducerimplementsRunnable{privateAbstractStorage storage;privateintnum;publicProducer(AbstractStorage storage){this.storage = storage;}@Overridepublicvoidrun(){prod(num);}privatevoidprod(intnum){while(true) {try{Thread.sleep(100);//需要添加延時腿准,不然生產(chǎn)者線程獲得執(zhí)行權(quán)時际起,一瞬間即可生產(chǎn)到倉庫上限值}catch(InterruptedException e) {e.printStackTrace();}storage.putIn(num);}}publicvoidsetNum(intnum){this.num = num;}}

消費者

使用實現(xiàn)Runnable接口方式創(chuàng)建消費者線程,將消費者消費操作放到重寫的run()方法中吐葱,實現(xiàn)消費者線程消費街望;

/** *@Data2018年12月11日 *@paramstorage //公共倉庫 *@paramnum //生產(chǎn)數(shù)量 *@constructorConsume(AbstractStorage) //構(gòu)造器 *@methodcons(int) //消費者生產(chǎn)方法 *@methodrun() //消費者線程執(zhí)行方法 *@methodsetNum(int) //設(shè)置消費者每次生產(chǎn)數(shù)量 */classConsumerimplementsRunnable{privateAbstractStorage storage;privateintnum;publicConsumer(AbstractStorage storage){this.storage = storage;}@Overridepublicvoidrun(){cons(num);}privatevoidcons(intnum){while(true) {try{Thread.sleep(100);//需要添加延時,不然消費者線程獲得執(zhí)行權(quán)時弟跑,一瞬間即可消費到倉庫下限值}catch(InterruptedException e) {e.printStackTrace();}storage.outOf(num);}}publicvoidsetNum(intnum){this.num = num;}

測試類

/**

* @Date 2018年12月11日

* @param storage //創(chuàng)建公共倉庫

* @param producer //創(chuàng)建生產(chǎn)者線程

* @param consumer //創(chuàng)建消費者線程

*/public class TestA {public static void main(String[] args) {AbstractStorage storage = new Storage();Producer producer = new Producer(storage);Consumer consumer = new Consumer(storage);producer.setNum(2);consumer.setNum(1);Threadt1= new Thread(producer);Threadt2= new Thread(consumer);t1.setName("producer");t2.setName("consumer");t1.start();t2.start();}}

測試輸出

寫在最后的話

使用wait/notify方法實現(xiàn)灾前,很多時候會出現(xiàn)一些奇怪的問題,例如:

1孟辑、兩者都持有鎖且等待對方釋放鎖哎甲,造成死鎖的情況;

2饲嗽、對未持有鎖的對象進行釋放鎖炭玫,導致IllegalMonitorStateException異常;

3貌虾、加鎖時吞加,雙方所加的鎖并非同一把鎖,導致數(shù)據(jù)異常尽狠;

關(guān)于生產(chǎn)者/消費者模型衔憨,現(xiàn)在更多是使用阻塞隊列(Queue)的方式來實現(xiàn),后續(xù)會接著去學習那一塊知識袄膏。

【注】以上為本人通過網(wǎng)上視頻教程以及實例代碼整理所得践图,如果出錯以及更好的提議,歡迎留言指正沉馆,一起學習码党。

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

每天都在分享文章,也每天都有人想要我出來給大家分享下怎么去學習Java斥黑。大家都知道闽瓢,我們是學Java全棧的,大家就肯定以為我有全套的Java系統(tǒng)教程心赶。沒錯扣讼,我是有Java全套系統(tǒng)教程,進扣裙【47】974【9726】所示缨叫,進群的時候記得表明自己想要學習什么椭符,不要用小號,這樣小編才好給你們發(fā)定向資源耻姥,今天小編就免費送!~

后記:對于大部分轉(zhuǎn)行的人來說销钝,找機會把自己的基礎(chǔ)知識補齊,邊工作邊補基礎(chǔ)知識琐簇,真心很重要蒸健∽恚“我們相信人人都可以成為一個程序員,現(xiàn)在開始似忧,找個師兄渣叛,帶你入門,學習的路上不再迷茫盯捌。這里是ja+va修真院淳衙,初學者轉(zhuǎn)行到互聯(lián)網(wǎng)行業(yè)的聚集地。"

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饺著,一起剝皮案震驚了整個濱河市箫攀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌幼衰,老刑警劉巖靴跛,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異渡嚣,居然都是意外死亡汤求,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門严拒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扬绪,“玉大人,你說我怎么就攤上這事裤唠〖放#” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵种蘸,是天一觀的道長墓赴。 經(jīng)常有香客問我,道長航瞭,這世上最難降的妖魔是什么诫硕? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮刊侯,結(jié)果婚禮上章办,老公的妹妹穿的比我還像新娘。我一直安慰自己滨彻,他們只是感情好藕届,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著亭饵,像睡著了一般休偶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辜羊,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天踏兜,我揣著相機與錄音词顾,去河邊找鬼。 笑死碱妆,一個胖子當著我的面吹牛肉盹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播山橄,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼垮媒,長吁一口氣:“原來是場噩夢啊……” “哼舍悯!你這毒婦竟也來了航棱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤萌衬,失蹤者是張志新(化名)和其女友劉穎饮醇,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秕豫,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡朴艰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了混移。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祠墅。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖歌径,靈堂內(nèi)的尸體忽然破棺而出毁嗦,到底是詐尸還是另有隱情,我是刑警寧澤回铛,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布狗准,位于F島的核電站,受9級特大地震影響茵肃,放射性物質(zhì)發(fā)生泄漏腔长。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一验残、第九天 我趴在偏房一處隱蔽的房頂上張望捞附。 院中可真熱鬧,春花似錦您没、人聲如沸故俐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽药版。三九已至,卻和暖如春喻犁,著一層夾襖步出監(jiān)牢的瞬間槽片,已是汗流浹背何缓。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留还栓,地道東北人碌廓。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像剩盒,于是被迫代替她去往敵國和親谷婆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容