生產(chǎn)者消費(fèi)者模式詳解及如何通過(guò)java代碼實(shí)現(xiàn),很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供西充網(wǎng)站建設(shè)、西充做網(wǎng)站、西充網(wǎng)站設(shè)計(jì)、西充網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、西充企業(yè)網(wǎng)站模板建站服務(wù),十年西充做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
生產(chǎn)者消費(fèi)者模式說(shuō)明:
1.生產(chǎn)者只在倉(cāng)庫(kù)未滿時(shí)進(jìn)行生產(chǎn),倉(cāng)庫(kù)滿時(shí)生產(chǎn)者進(jìn)程被阻塞;
2.消費(fèi)者只在倉(cāng)庫(kù)非空時(shí)進(jìn)行消費(fèi),倉(cāng)庫(kù)為空時(shí)消費(fèi)者進(jìn)程被阻塞;
3.當(dāng)消費(fèi)者發(fā)現(xiàn)倉(cāng)庫(kù)為空時(shí)會(huì)通知生產(chǎn)者生產(chǎn);
4.當(dāng)生產(chǎn)者發(fā)現(xiàn)倉(cāng)庫(kù)滿時(shí)會(huì)通知消費(fèi)者消費(fèi);
實(shí)現(xiàn)的關(guān)鍵:
共享內(nèi)存中的兩個(gè)同步方法,及同步方法中wait()方法的調(diào)用,同步保證了對(duì)象只能被一個(gè)線程占用,wait保證了當(dāng)線程在等待過(guò)程中釋放鎖,使得其他對(duì)象有機(jī)會(huì)獲得鎖。
在一個(gè)對(duì)象中,用synchonized聲明的方法為同步方法。Java中有一個(gè)同步模型-監(jiān)視器,負(fù)責(zé)管理線程對(duì)對(duì)象中的同步方法的訪問(wèn),它的原理是:賦予該對(duì)象唯一一把'鑰匙',當(dāng)多個(gè)線程進(jìn)入對(duì)象,只有取得該對(duì)象鑰匙的線程才可以訪問(wèn)同步方法,其它線程在該對(duì)象中等待,直到該線程用wait()方法放棄這把鑰匙,其它等待的線程搶占該鑰匙,搶占到鑰匙的線程后才可得以執(zhí)行,而沒(méi)有取得鑰匙的線程仍被阻塞在該對(duì)象中等待。 總而言之,synchonized使得只有一個(gè)線程能進(jìn)入臨界代碼區(qū)。
代碼實(shí)現(xiàn):
package com.thread; public class ProducerConsumer { public static void main(String[] args) { ShareData sd = new ShareData(); new Producer(sd).start(); new Consumer(sd).start(); } } class Producer extends Thread{ private ShareData sd; public Producer(ShareData sd){ this.sd = sd; } @Override public void run() { for(int i = 0; i < 20; i++){ int product = (int)(Math.random()*1000); sd.setArray(product); try { Thread.sleep((int)(Math.random()*200)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer extends Thread{ private ShareData sd; public Consumer(ShareData sd){ this.sd = sd; } @Override public void run() { for(int i = 0; i < 20; i++){ sd.getArray(); try { Thread.sleep((int)(Math.random()*200)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class ShareData{ private static int shareArray[] = new int[10]; private int count; private int in; private int out; ShareData(){ this.count = 0; this.in = 0; this.out = 0; } public synchronized void setArray(int product){ try{ while(count >= shareArray.length){ System.out.println("array full."); this.wait(); } this.notify(); }catch (Exception e) { e.printStackTrace(); } shareArray[in] = product; count++; System.out.println("produce: " + product); in = (in + 1) % shareArray.length; } public synchronized int getArray(){ try{ while(count <= 0){ System.out.println("array empty."); this.wait(); } this.notify(); }catch(Exception e){ e.printStackTrace(); } int consume = shareArray[out]; count--; System.out.println("consume: " + consume); out = (out + 1) % shareArray.length; notify(); return consume; } }
輸出代碼(每次都不同):
array empty. produce: 86 consume: 86 array empty. produce: 232 consume: 232 array empty. produce: 438 consume: 438 produce: 272 consume: 272 array empty. produce: 495 consume: 495 produce: 354 produce: 533 consume: 354 produce: 92 consume: 533 produce: 374 consume: 92 produce: 441 produce: 141 consume: 374 consume: 441 consume: 141 array empty. produce: 68 consume: 68 produce: 978 consume: 978 array empty. produce: 737 consume: 737 array empty. produce: 904 consume: 904 array empty. produce: 613 consume: 613 array empty. produce: 812 consume: 812 produce: 726 produce: 326 consume: 726 produce: 305 consume: 326 consume: 305
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。