您好,登錄后才能下訂單哦!
這篇“java中生產者和消費者問題實例分析”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“java中生產者和消費者問題實例分析”文章吧。
假設倉庫中只能存放一件產品,生產者將生產出來的產品放入倉庫,消費者將倉庫中產品取走消費
如果倉庫中沒有產品,則生產者將產品放入倉庫,否則停止生產并等待,直到倉庫中的產品被消費者取走為止
如果倉庫中放有產品,則消費者可以將產品取走消費,否則停止消費并等待,直到倉庫中再次放入產品為止
這是一個線程同步問題,生產者和消費者共享同一個資源,并且生產者和消費者之間相互依賴,互為條件。
對于生產者,沒有生產產品之前,要通知消費者等待,而生產了產品之后,又需要馬上通知消費者消費
對于消費者,在消費之后,要通知生產者已經結束消費,需要生產新的產品以供消費
在生產者消費者問題中,僅有synchronized是不夠的
synchronized可阻止并發(fā)更新同一個共享資源,實現了同步
synchronized不能用來實現不同線程之間的消息傳遞(通信)
Java提供了幾個方法解決線程之間的通信問題
方法名 | 作用 |
---|---|
wait() | 表示線程一直等待,直到其他線程通知,與sleep不同,wait()會釋放鎖 |
wait(long timeout) | 指定等待的毫秒數 |
notify() | 喚醒一個處于等待狀態(tài)的線程 |
notifyAll() | 喚醒同一個對象上所有調用wait()方法的線程,優(yōu)先級別高的線程優(yōu)先調度 |
注意:均是Object類的方法,都只能在同步方法或者同步代碼塊中使用,否則會拋出異常
生產者:負責生產數據的模塊(可能是方法、對象、線程、進程)
消費者:負責處理數據的模塊(可能是方法、對象、線程、進程)
緩沖區(qū):消費者不能直接使用生產者的數據,他們之間有個“緩沖區(qū)”
生產者將生產好的數據放入緩沖區(qū),消費者從緩沖區(qū)拿出數據
代碼案例
//使用緩沖區(qū)解決生產者消費者模型 public class TestPC { public static void main(String[] args) { SynContainer container = new SynContainer(); new Producer(container).start(); new Consumer(container).start(); } } class Producer extends Thread{ SynContainer synContainer; public Producer(SynContainer synContainer){ this.synContainer = synContainer; } // 生產 @Override public void run() { for (int i = 0; i < 100; i++) { synContainer.push(new Chicken(i)); System.out.println("生產了"+i+"只雞"); } } } class Consumer extends Thread{ SynContainer synContainer; public Consumer(SynContainer synContainer){ this.synContainer = synContainer; } // 消費 @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("消費了-->"+synContainer.pop().id+"只雞"); } } } //產品 class Chicken{ int id; public Chicken(int id) { this.id = id; } } //緩沖區(qū) class SynContainer{ Chicken[] chickens = new Chicken[10]; int count = 0; //生產者放入產品 public synchronized void push(Chicken chicken){ //如果容器滿了就要等到消費者消費 if (count==chickens.length){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } //通知消費者消費,自身進入等待 } //沒有滿的話則生產 chickens[count] = chicken; count++; //通知消費者消費 this.notifyAll(); } //生產者消費產品 public synchronized Chicken pop(){ if (count==0){ //等待生產者生產 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } count--; Chicken chicken = chickens[count]; //消費了,可以通知生產者繼續(xù)生產 this.notifyAll(); return chicken; } }
通過標志位 true 或者 false 來進行判斷
代碼案例
//信號燈法測試生產者消費者模型 即標志位 public class TestPC2 { public static void main(String[] args) { TV tv = new TV(); new Player(tv).start(); new Audiance(tv).start(); } } //生產者-->演員 class Player extends Thread { TV tv; public Player(TV tv){ this.tv = tv; } @Override public void run() { for (int i = 0; i < 20; i++) { if (i%2==0){ this.tv.play("天天向上"); }else { this.tv.play("抖音廣告"); } } } } //消費者-->觀眾 class Audiance extends Thread{ TV tv; public Audiance(TV tv){ this.tv = tv; } @Override public void run() { for (int i = 0; i < 20; i++) { tv.watch(); } } } //產品-->節(jié)目 class TV{ //演員表演 觀眾等待 T //觀眾觀看 演員等待 F String show;//表演的節(jié)目 boolean flag = true; //表演 public synchronized void play(String show){ if (!flag){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("演員表演了:"+show); //通知觀眾 this.notifyAll(); this.show = show; this.flag = !this.flag; } //觀看 public synchronized void watch(){ if (flag){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("觀看了"+show); //通知演員表演 this.notifyAll(); this.flag = !this.flag; } }
以上就是關于“java中生產者和消費者問題實例分析”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。