Java随笔记 - 用wait()和notify()实现生产者消费者模型
生产者消费者问题
-
在多线程的相关基础知识中,生产者消费者是一个很经典的问题。理论上的概念就不多说了,总的来说就是抽象出三个对象,仓库、生产者和消费者,他们之间大致有以下几点联系:
-
仓库为空时消费者停止消费;
-
仓库放满时生产者停止生产;
-
消费者成功消费后通知生产者进行生产;
-
生产者成功生产后通知消费者进行消费;
-
-
上述联系通过wait()和notify()方法即可进行简单的代码实现,当然还可以通过使用并发容器等方式进行实现,后续补上~
代码实现
-
仓库
package multithread; import java.util.ArrayList; import java.util.List; /** * @author jiangnanmax * @email jiangnanmax@gmail.com * @description Container * @date 2021/1/5 **/ public class Container { private List<Integer> _container; private int maxSize; public Container(int maxSize) { this.maxSize = maxSize; this._container = new ArrayList(); } public void put(int value) { this._container.add(value); } public int get() { int ret = this._container.get(0); this._container.remove(0); return ret; } public boolean isFull() { return this._container.size() >= this.maxSize; } public boolean isEmpty() { return this._container.isEmpty(); } }
-
生产者
package multithread; /** * @author jiangnanmax * @email jiangnanmax@gmail.com * @description Producer * @date 2021/1/5 **/ public class Producer { private Container container; public Producer(Container container) { this.container = container; } public void produce(int value) throws InterruptedException { synchronized (container) { while (container.isFull()) { System.out.println("current: " + System.currentTimeMillis() + ", container is full, producer wait."); container.wait(); } container.put(value); System.out.println("current: " + System.currentTimeMillis() + ", put value " + value + " into container."); container.notify(); } } }
-
消费者
package multithread; /** * @author jiangnanmax * @email jiangnanmax@gmail.com * @description Consumer * @date 2021/1/5 **/ public class Consumer { private Container container; public Consumer(Container container) { this.container = container; } public int consume() throws InterruptedException { synchronized (container) { while (container.isEmpty()) { System.out.println("current: " + System.currentTimeMillis() + ", container is empty, consumer wait."); container.wait(); } int value = container.get(); System.out.println("current: " + System.currentTimeMillis() + ", get value " + value + " form container."); container.notify(); } return 0; } }
-
主函数
package multithread; /** * @author jiangnanmax * @email jiangnanmax@gmail.com * @description Main * @date 2021/1/5 **/ public class Main { public static final int _COUNT = 100; public static void main(String[] args) { Container container = new Container(10); Producer producer = new Producer(container); Consumer consumer = new Consumer(container); Thread producerThread = new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= _COUNT; i++) { try { producer.produce(i); } catch (InterruptedException e) { e.printStackTrace(); } } } }); Thread consumerThread = new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= _COUNT; i++) { try { consumer.consume(); } catch (InterruptedException e) { e.printStackTrace(); } } } }); consumerThread.start(); // try { // Thread.sleep(1000); // } catch (InterruptedException e) { // e.printStackTrace(); // } producerThread.start(); } }