您好,登錄后才能下訂單哦!
小編給大家分享一下Java多線程中生產者消費者模型的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
生產者消費者模型
生產者:生產任務的個體;
消費者:消費任務的個體;
緩沖區:是生產者和消費者之間的媒介,對生產者和消費者解耦。
當
緩沖區元素為滿,生產者無法生產,消費者繼續消費;
緩沖區元素為空,消費者無法消費,生產者繼續生產;
wait()/notify()生產者消費者模型
制作一個簡單的緩沖區ValueObject,value為空表示緩沖區為空,value不為空表示緩沖區滿
public class ValueObject { public static String value = ""; }
生產者,緩沖區滿則wait(),不再生產,等待消費者notify(),緩沖區為空則開始生產
public class Producer { private Object lock; public Producer(Object lock) { this.lock = lock; } public void setValue() { try { synchronized (lock) { if (!ValueObject.value.equals("")) lock.wait(); String value = System.currentTimeMillis() + "_" + System.nanoTime(); System.out.println("Set的值是:" + value); ValueObject.value = value; lock.notify(); } } catch (InterruptedException e) { e.printStackTrace(); } } }
消費者,緩沖區為空則wait(),等待生產者notify(),緩沖區為滿,消費者開始消費
public class Customer { private Object lock; public Customer(Object lock) { this.lock = lock; } public void getValue() { try { synchronized (lock) { if (ValueObject.value.equals("")) lock.wait(); System.out.println("Get的值是:" + ValueObject.value); ValueObject.value = ""; lock.notify(); } } catch (InterruptedException e) { e.printStackTrace(); } } }
main方法,啟動一個生產者和一個消費者
public class Main { public static void main(String[] args) { Object lock = new Object(); final Producer producer = new Producer(lock); final Customer customer = new Customer(lock); Runnable producerRunnable = new Runnable() { public void run() { while (true) { producer.setValue(); } } }; Runnable customerRunnable = new Runnable() { public void run() { while (true) { customer.getValue(); } } }; Thread producerThread = new Thread(producerRunnable); Thread CustomerThread = new Thread(customerRunnable); producerThread.start(); CustomerThread.start(); } }
運行結果如下
Set的值是:1564733938518_27520480474279 Get的值是:1564733938518_27520480474279 Set的值是:1564733938518_27520480498378 Get的值是:1564733938518_27520480498378 Set的值是:1564733938518_27520480540254 Get的值是:1564733938518_27520480540254 ······
生產者和消費者交替運行,生產者生產一個字符串,緩沖區為滿,消費者消費一個字符串,緩沖區為空,循環往復,滿足生產者/消費者模型。
await()/signal()生產者/消費者模型
緩沖區
public class ValueObject { public static String value = ""; }
ThreadDomain48繼承ReentrantLock,set方法生產,get方法消費
public class ThreadDomain48 extends ReentrantLock { private Condition condition = newCondition(); public void set() { try { lock(); while (!"".equals(ValueObject.value)) condition.await(); ValueObject.value = "123"; System.out.println(Thread.currentThread().getName() + "生產了value, value的當前值是" + ValueObject.value); condition.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { unlock(); } } public void get() { try { lock(); while ("".equals(ValueObject.value)) condition.await(); ValueObject.value = ""; System.out.println(Thread.currentThread().getName() + "消費了value, value的當前值是" + ValueObject.value); condition.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { unlock(); } } }
MyThread41啟動兩個生產線程和一個消費線程
public class MyThread41 { public static void main(String[] args) { final ThreadDomain48 td = new ThreadDomain48(); Runnable producerRunnable = new Runnable() { public void run() { for (int i = 0; i < Integer.MAX_VALUE; i++) td.set(); } }; Runnable customerRunnable = new Runnable() { public void run() { for (int i = 0; i < Integer.MAX_VALUE; i++) td.get(); } }; Thread ProducerThread1 = new Thread(producerRunnable); ProducerThread1.setName("Producer1"); Thread ProducerThread2 = new Thread(producerRunnable); ProducerThread2.setName("Producer2"); Thread ConsumerThread = new Thread(customerRunnable); ConsumerThread.setName("Consumer"); ProducerThread1.start(); ProducerThread2.start(); ConsumerThread.start(); } }
輸出結果如下
Producer1生產了value, value的當前值是123 Consumer消費了value, value的當前值是 Producer1生產了value, value的當前值是123
為什么Producer2無法生產,消費者無法消費呢?是因為此時緩沖區為滿,Producer1的notify()應該喚醒Consumer卻喚醒了Producer2,導致Producer2因為緩沖區為滿和Consumer沒有被喚醒而處于waiting狀態,此時三個線程均在等待,出現了假死。
解決方案有兩種:
1.讓生產者喚醒所有線程,在set方法中使用condition.signalAll();
2.使用兩個Condition,生產者Condition和消費者Condition,喚醒指定的線程;
正常輸入如下:
······ Producer2生產了value, value的當前值是123 Consumer消費了value, value的當前值是 Producer2生產了value, value的當前值是123 Consumer消費了value, value的當前值是 Producer2生產了value, value的當前值是123 Consumer消費了value, value的當前值是 Producer1生產了value, value的當前值是123 Consumer消費了value, value的當前值是 Producer1生產了value, value的當前值是123 Consumer消費了value, value的當前值是 Producer1生產了value, value的當前值是123 Consumer消費了value, value的當前值是 Producer1生產了value, value的當前值是123 Consumer消費了value, value的當前值是 Producer1生產了value, value的當前值是123 Consumer消費了value, value的當前值是 ······
以上是“Java多線程中生產者消費者模型的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。