java實現生產者消費者問題
引言
生產者和消費者問題是執行緒模型中的經典問題:生產者和消費者在同一時間段內共用同一個儲存空間,如下圖所示,生產者向空間裡存放資料,而消費者取用資料,如果不加以協調可能會出現以下情況:
生產者消費者圖
儲存空間已滿,而生產者佔用著它,消費者等著生產者讓出空間從而去除產品,生產者等著消費者消費產品,從而向空間中新增產品。互相等待,從而發生死鎖。
JAVA解決執行緒模型的三種方式
1、wait()和notify()
import java.util.LinkedList;public class ProducerConsumer { private LinkedList<Object> storeHouse = new LinkedList<Object>(); private int MAX = 10; public ProducerConsumer() { } public void start() { new Producer().start(); new Comsumer().start(); } class Producer extends Thread { public void run() { while (true) { synchronized (storeHouse) { try { while (storeHouse.size() == MAX) { System.out.println("storeHouse is full , please wait"); storeHouse.wait(); } Object newOb = new Object(); if (storeHouse.add(newOb)) { System.out.println("Producer put a Object to storeHouse"); Thread.sleep((long) (Math.random() * 3000)); storeHouse.notify(); } } catch (InterruptedException ie) { System.out.println("producer is interrupted!"); } } } } } class Comsumer extends Thread { public void run() { while (true) { synchronized (storeHouse) { try { while (storeHouse.size() == 0) { System.out.println("storeHouse is empty , please wait"); storeHouse.wait(); } storeHouse.removeLast(); System.out.println("Comsumer get a Object from storeHouse"); Thread.sleep((long) (Math.random() * 3000)); storeHouse.notify(); } catch (InterruptedException ie) { System.out.println("Consumer is interrupted"); } } } } } public static void main(String[] args) throws Exception { ProducerConsumer pc = new ProducerConsumer(); pc.start(); } }
2、await()和signal(),即執行緒鎖的方式
package sort;import java.util.LinkedList;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ProducerConsumer { private LinkedList<Object> myList = new LinkedList<Object>(); private int MAX = 10; private final Lock lock = new ReentrantLock(); private final Condition full = lock.newCondition(); private final Condition empty = lock.newCondition(); public ProducerConsumer() { } public void start() { new Producer().start(); new Consumer().start(); } public static void main(String[] args) throws Exception { ProducerConsumer s2 = new ProducerConsumer(); s2.start(); } class Producer extends Thread { public void run() { while (true) { lock.lock(); try { while (myList.size() == MAX) { System.out.println("warning: it's full!"); full.await(); } Object o = new Object(); if (myList.add(o)) { System.out.println("Producer: " + o); empty.signal(); } } catch (InterruptedException ie) { System.out.println("producer is interrupted!"); } finally { lock.unlock(); } } } } class Consumer extends Thread { public void run() { while (true) { lock.lock(); try { while (myList.size() == 0) { System.out.println("warning: it's empty!"); empty.await(); } Object o = myList.removeLast(); System.out.println("Consumer: " + o); full.signal(); } catch (InterruptedException ie) { System.out.println("consumer is interrupted!"); } finally { lock.unlock(); } } } } }
3、阻塞佇列的方式
import java.util.concurrent.*;public class ProducerConsumer { // 建立一個阻塞佇列 private LinkedBlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(10); public ProducerConsumer() { } public void start() { new Producer().start(); new Consumer().start(); } public static void main(String[] args) throws Exception { ProducerConsumer s3 = new ProducerConsumer(); s3.start(); } class Producer extends Thread { public void run() { while (true) { try { Object o = new Object(); // 取出一個物件 queue.put(o); System.out.println("Producer: " + o); } catch (InterruptedException e) { System.out.println("producer is interrupted!"); } // } } } } class Consumer extends Thread { public void run() { while (true) { try { // 取出一個物件 Object o = queue.take(); System.out.println("Consumer: " + o); } catch (InterruptedException e) { System.out.println("producer is interrupted!"); } // } } } } }
結論
三種方式原理一致,都是對獨佔空間加鎖,阻塞和喚醒執行緒,第一種方式比較傳統,第三種方式最簡單,只需儲存和取用,執行緒同步的操作交由LinkedBlockingQueue全權處理。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/758/viewspace-2816523/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java實現生產者和消費者Java
- 生產者消費者問題-C++程式碼實現C++
- 生產者與消費者問題
- linux 生產者與消費者問題Linux
- python中多程式消費者生產者問題Python
- Thinking in Java---執行緒通訊+三種方式實現生產者消費者問題ThinkingJava執行緒
- 生產者消費者
- 使用BlockQueue實現生產者和消費者模式BloC模式
- 使用Disruptor實現生產者和消費者模型模型
- python中多執行緒消費者生產者問題Python執行緒
- 作業系統—生產者消費者問題詳解作業系統
- 「Kafka應用」PHP實現生產者與消費者KafkaPHP
- 生產者消費者模式模式
- 生產者消費者模型模型
- 訊號量實現生產者消費者(程式碼邏輯有問題,不適合多個消費者,不常用)
- 面試必問:訊號量與生產者消費者問題!面試
- C++ condition_variable 實現生產者消費者模型C++模型
- 使用wait()與notifyAll()實現生產者與消費者模式AI模式
- python 生產者消費者模式Python模式
- java編寫生產者/消費者模式的程式。Java模式
- Java多執行緒——生產者消費者示例Java執行緒
- 生產消費者模式模式
- 生產者消費者模式,以及基於BlockingQueue的快速實現模式BloC
- python 多執行緒實現生產者與消費者模型Python執行緒模型
- 6、JUC:傳統的生產者消費者問題,防止虛假喚醒問題
- 九、生產者與消費者模式模式
- ActiveMQ 生產者和消費者demoMQ
- java學習回顧---生產者與消費者問題以及多執行緒補充Java執行緒
- 生產消費問題
- 多執行緒併發如何高效實現生產者/消費者?執行緒
- Java多執行緒程式設計(同步、死鎖、生產消費者問題)Java執行緒程式設計
- 生產者與消費者之Android audioAndroid
- 新手練習-消費者生產者模型模型
- 使用Python佇列和多執行緒實現生產者消費者Python佇列執行緒
- 多生產者-消費者中假死現象的處理
- synchronized同步程式+生產者消費者模式(訊號燈)解除可能出現的資源問題synchronized模式
- 分享一個生產者-消費者的真實場景
- Java 多執行緒基礎(十二)生產者與消費者Java執行緒