Producer Consumer 模式
Producer Consumer 模式是指一个负责生产,一个负责消费。
核心是生产者安全地将数据交给消费者。
实际案例
类信息概览:
类名 | 说明 |
---|---|
Main.java | 方法的总入口 |
ConsumerCakeThread.java | 消费蛋糕的线程 |
Table.java | 放置蛋糕的桌子 |
BlockingQueueTable.java | BlockingQueue 实现 |
ProducerCakeThread.java | 生产蛋糕的线程 |
定义
- ConsumerCakeThread.java
package com.github.houbb.thread.learn.easy.learn.producer.consumer;import java.util.Random;public class ConsumerCakeThread extends Thread {
private String name;private final Table table;public ConsumerCakeThread(String name, Table table) {super(name);this.table = table;}@Overridepublic void run() {Random random = new Random(1000L);try {while(true) {Thread.sleep(random.nextInt(1000));String cake = table.take();}} catch (InterruptedException e) {e.printStackTrace();}}}
- Table.java
package com.github.houbb.thread.learn.easy.learn.producer.consumer;/*** @see BlockingQueueTable 可以被这个替换*/
public class Table {
/*** 存放蛋糕的数组*/private String[] cakeArray;/*** 头*/private int head;/*** 尾巴*/private int tail;private int count;private final int size;public Table(int size) {this.size = size;cakeArray = new String[size];this.head = 0;this.tail = 0;this.count = 0;}public synchronized void put(final String cakeName) throws InterruptedException {while(count >= size) {wait();}cakeArray[tail] = cakeName;count++;tail = (tail + 1) % size;System.out.println(Thread.currentThread().getName() + " put cake " + cakeName);notifyAll();}public synchronized String take() throws InterruptedException {while (count <= 0) {wait();}String result = cakeArray[head];head = (head + 1) % size;count--;System.out.println(Thread.currentThread().getName() + " take cake " + result);notifyAll();return result;}}
- BlockingQueueTable.java
package com.github.houbb.thread.learn.easy.learn.producer.consumer;import java.util.concurrent.ArrayBlockingQueue;/*** 使用 queue*/
public class BlockingQueueTable extends ArrayBlockingQueue<String> {
public BlockingQueueTable(int size) {super(size);}public void put(final String cakeName) throws InterruptedException {super.put(cakeName);}public String take() throws InterruptedException {return super.take();}}
- ProducerCakeThread.java
package com.github.houbb.thread.learn.easy.learn.producer.consumer;import java.util.Random;public class ProducerCakeThread extends Thread {
private final Table table;private static int id = 0;public ProducerCakeThread(String name, Table table) {super(name);this.table = table;}@Overridepublic void run() {Random random = new Random(1000L);try {while(true) {String cakeName = getName()+"-"+genId();Thread.sleep(random.nextInt(1000));table.put(cakeName);}} catch (InterruptedException e) {e.printStackTrace();}}private static synchronized int genId() {return id++;}}
测试
- Main.java
package com.github.houbb.thread.learn.easy.learn.producer.consumer;public class Main {
public static void main(String[] args) {Table table = new Table(3);new ConsumerCakeThread("ConsumerCake", table).start();new ProducerCakeThread("ProducerCake", table).start();}}
- 测试结果
ProducerCake put cake ProducerCake-0
ConsumerCake take cake ProducerCake-0
ProducerCake put cake ProducerCake-1
ConsumerCake take cake ProducerCake-1
ProducerCake put cake ProducerCake-2
ConsumerCake take cake ProducerCake-2
ProducerCake put cake ProducerCake-3
ConsumerCake take cake ProducerCake-3
ProducerCake put cake ProducerCake-4
ConsumerCake take cake ProducerCake-4
ProducerCake put cake ProducerCake-5
ConsumerCake take cake ProducerCake-5
实现方式
UML & Code
UML
UML 图示如下
Code
代码地址
Producer Consumer
系列导航
多线程系列导航