生产者与消费者(二)---await与 signal
生活随笔
收集整理的這篇文章主要介紹了
生产者与消费者(二)---await与 signal
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前面闡述了實現生產者與消費者問題的一種方式:wait() / notify()方法,本文繼續闡述多線程的經典問題---生產者與消費者的第二種方式:await() / signal()方法。
await() / signal()方法
在JDK5.0之后,Java提供了更加健壯的線程處理機制,包括同步、鎖定、線程池等,它們可以實現更細粒度的線程控制。await()和signal()就是其中用來做同步的兩種方法,它們的功能基本上和wait() / nofity()相同,完全可以取代它們,但是它們和新引入的鎖定機制Lock直接掛鉤,具有更大的靈活性。通過在Lock對象上調用newCondition()方法,將條件變量和一個鎖對象進行綁定,進而控制并發程序訪問競爭資源的安全。
緩沖區(倉庫):
import java.util.LinkedList; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class Storage {// 倉庫最大存儲量 private final int MAX_SIZE = 100; // 倉庫存儲的載體 private LinkedList<Object> list = new LinkedList<Object>(); // 鎖 private final Lock lock = new ReentrantLock(); // 倉庫滿的條件變量 private final Condition full = lock.newCondition(); // 倉庫空的條件變量 private final Condition empty = lock.newCondition(); // 生產num個產品 public void produce(int num){ // 獲得鎖 lock.lock(); // 如果倉庫剩余容量不足 while (list.size() + num > MAX_SIZE){ System.out.println("【要生產的產品數量】:" + num + "【庫存量】:" + list.size()+ "暫時不能執行生產任務!"); try{ // 由于條件不滿足,生產阻塞 full.await(); } catch (InterruptedException e){ e.printStackTrace(); } } // 生產條件滿足情況下,生產num個產品 for (int i = 1; i <= num; ++i){ list.add(new Object()); } System.out.println("【已經生產產品數】:" + num + "/t【現倉儲量為】:" + list.size()); // 喚醒其他所有線程 full.signalAll(); empty.signalAll(); // 釋放鎖 lock.unlock(); } // 消費num個產品 public void consume(int num) { // 獲得鎖 lock.lock(); // 如果倉庫存儲量不足 while (list.size() < num){ System.out.println("【要消費的產品數量】:" + num + "【庫存量】:" + list.size()+ "暫時不能執行生產任務!"); try{ // 由于條件不滿足,消費阻塞 empty.await(); } catch (InterruptedException e){ e.printStackTrace(); } } // 消費條件滿足情況下,消費num個產品 for (int i = 1; i <= num; ++i){ list.remove(); } System.out.println("【已經消費產品數】:" + num + "【現倉儲量為】:" + list.size()); // 喚醒其他所有線程 full.signalAll(); empty.signalAll(); // 釋放鎖 lock.unlock(); } // set/get方法 public int getMAX_SIZE() { return MAX_SIZE; } public LinkedList<Object> getList() { return list; } public void setList(LinkedList<Object> list) { this.list = list; } }?
生產者:
public class Producer extends Thread {// 每次生產的產品數量 private int num; // 所在放置的倉庫 private Storage storage; // 構造函數,設置倉庫 public Producer(Storage storage){ this.storage = storage; } // 線程run函數 public void run(){ produce(num); } // 調用倉庫Storage的生產函數 public void produce(int num){ storage.produce(num); } // get/set方法 public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Storage getStorage() { return storage; } public void setStorage(Storage storage) { this.storage = storage; } }?
消費者:
public class Consumer extends Thread {// 每次消費的產品數量 private int num; // 所在放置的倉庫 private Storage storage; // 構造函數,設置倉庫 public Consumer(Storage storage){ this.storage = storage; } // 線程run函數 public void run(){ consume(num); } // 調用倉庫Storage的生產函數 public void consume(int num){ storage.consume(num); } // get/set方法 public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Storage getStorage() { return storage; } public void setStorage(Storage storage) { this.storage = storage; } }?
測試類:
public class Test {public static void main(String[] args) {// 倉庫對象 Storage storage = new Storage(); // 生產者對象 Producer p1 = new Producer(storage); Producer p2 = new Producer(storage); Producer p3 = new Producer(storage); Producer p4 = new Producer(storage); Producer p5 = new Producer(storage); Producer p6 = new Producer(storage); Producer p7 = new Producer(storage); // 消費者對象 Consumer c1 = new Consumer(storage); Consumer c2 = new Consumer(storage); Consumer c3 = new Consumer(storage); // 設置生產者產品生產數量 p1.setNum(10); p2.setNum(10); p3.setNum(10); p4.setNum(10); p5.setNum(10); p6.setNum(10); p7.setNum(80); // 設置消費者產品消費數量 c1.setNum(50); c2.setNum(20); c3.setNum(30); // 線程開始執行 c1.start(); c2.start(); c3.start(); p1.start(); p2.start(); p3.start(); p4.start(); p5.start(); p6.start(); p7.start(); } }?
轉載于:https://www.cnblogs.com/Kevin-mao/p/5950758.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的生产者与消费者(二)---await与 signal的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python基础教程学习笔记十二
- 下一篇: 【python】lxml处理命名空间