wait、notify應用場景(生產者-消費者模式)
阿新 • • 發佈:2018-12-15
Java實現生產者消費者的方式有:wait && notify、BlockingQueue、Lock && Condition等
wait、notify注意事項:
(1)可以使用wait()和notify()方法在Java中實現執行緒間通訊。不只是一個或兩個執行緒,而是多個執行緒可以使用這些方法相互通訊。
(2)在synchronized方法或synchronized塊中呼叫wait(),notify()和notifyAll()方法,否則JVM將丟擲IllegalMonitorStateException。
(3)從while(條件)迴圈呼叫wait和notify方法,而不是從if()塊呼叫,因為要重複檢查條件,而不僅僅是一次。
(4)多使用notifyAll方法而不是notify。
下面是wait、notify等待通知實現的生產者-消費者模式:
生產者:
/** * 生產者 * * @author tangquanbin * @date 2018/12/15 11:13 */ public class Producer implements Runnable { /** * 產品容器 */ private final List<Integer> container; public Producer(List<Integer> container) { this.container = container; } /** * 生產者生產方法 * * @throws InterruptedException */ private void produce() throws InterruptedException { //產品容器容量 int capacity = 5; synchronized (container) { //當容器已滿,暫停生產 while (container.size() == capacity) { System.out.println("...容器已經滿了,暫停生產..."); container.wait(); } Random random = new Random(); int p = random.nextInt(50); //模擬1秒生產一個產品 TimeUnit.MILLISECONDS.sleep(1000); System.out.println("生產產品:" + p); container.add(p); container.notifyAll(); } } @Override public void run() { while (true) { try { produce(); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("produce error"); } } } }
消費者:
/** * 消費者 * @author tangquanbin * @date 2018/12/15 11:13 */ public class Consumer implements Runnable{ /** * 產品容器 */ private final List<Integer> container; public Consumer(List<Integer> container) { this.container = container; } /** * 消費者消費產品 */ private void consume() throws InterruptedException { synchronized (container){ while (container.isEmpty()){ System.out.println("...容器是空的,暫停消費..."); container.wait(); } Integer p = container.remove(0); //模擬1秒消費一個產品 TimeUnit.MILLISECONDS.sleep(1000); System.out.println("消費產品:" + p); container.notifyAll(); } } @Override public void run() { while (true){ try { consume(); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("consume error"); } } } }
測試:
public class ProducerConsumerTest { public static void main(String[] args) { List<Integer> container = new ArrayList<>(); Thread producer = new Thread(new Producer(container)); Thread consumer = new Thread(new Consumer(container)); producer.start(); consumer.start(); } }
輸出:
生產產品:14 生產產品:17 消費產品:14 生產產品:0 生產產品:39 生產產品:4 生產產品:3 ...容器已經滿了,暫停生產... 消費產品:17 消費產品:0 消費產品:39 消費產品:4 消費產品:3 ...容器是空的,暫停消費... 生產產品:25 生產產品:33 生產產品:17 消費產品:25 消費產品:33 消費產品:17 ...容器是空的,暫停消費...