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;
}
@Override
public 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;
}
@Override
public 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
代码地址