Java简易版生产者消费者模型
一、概述
一共两个线程,一个线程生产产品,一个线程消费产品,使用同步代码块方法,同步两个线程。当产品没有时,通知生产者生产,生产者生产后,通知消费者消费,并等待消费者消费完。
需要注意的是,有可能出现,停止生产产品后,消费者还没未来得及消费生产者生产的最后一个产品,就结束消费,导致最后一个产品没有被消费。
本例使用synchronize以及wait()、notify()实现简易版的线程者消费者模型。
二、测试用例
这里的产品用笔来演示,每只笔都有其编号code
一共有四个类:分别是生产者类,产品类,消费者类,测试类
产品
package test.exception.producer_consumer_model;
/*
假设为产品为笔
*/
public class Production {
private String type = "";
private String color = "";
private long code = 0; // 产品编号
private boolean isProduced = false; // 是否生产完成 初始状态为未生产状态
private boolean isContinueProduce = true; // 是否停产该产品
public void setContinueProduce(boolean continueProduce) {
isContinueProduce = continueProduce;
}
public void setCode(long code) {
this.code = code;
}
public Production(){
}
public boolean isContinueProduce() {
return isContinueProduce;
}
public void setType(String type) {
this.type = type;
}
public void setColor(String color) {
this.color = color;
}
public void setProduced(boolean produced) {
isProduced = produced;
}
public boolean isProduced() {
return isProduced;
}
@Override
public String toString() {
return color + type + "-" + code;
}
}
生产者
package test.exception.producer_consumer_model;
public class Producer implements Runnable {
private final Production pen; // 产品
public Producer(Production pen) {
this.pen = pen;
}
// 生产
public void produce() {
long code = 0;
while (this.pen.isContinueProduce()) {
synchronized (this.pen) {
if (this.pen.isProduced()) {
try {
this.pen.wait(); // 等待消费者消费
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 开始生产
this.pen.setType("铅笔");
this.pen.setColor("蓝色");
this.pen.setCode(code++);
this.pen.setProduced(true);
System.out.println(this.pen + " is produced");
this.pen.notify();
}
}
System.out.println("finish producing");
}
@Override
public void run() {
produce();
}
}
消费者
package test.exception.producer_consumer_model;
public class Consumer implements Runnable {
private final Production pen;
public Consumer(Production pen) {
this.pen = pen;
}
// 持续消费
public void consumer() {
while (this.pen.isContinueProduce()) {
synchronized (this.pen) {
if (!this.pen.isProduced()) {
try {
this.pen.wait(); // 等待生产者生产
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.pen + " is consumed"); // 使用
this.pen.setProduced(false); // 使用完后更新状态
this.pen.notify();
}
}
// 确保停止生产后,能够使用最后生产的一支笔
if (this.pen.isProduced()) {
System.out.println(this.pen + " is consumed");
}
System.out.println("finish using");
}
@Override
public void run() {
consumer();
}
}
主线程测试
package test.exception.producer_consumer_model;
public class Demo {
public static void main(String[] args) throws InterruptedException {
Production pen = new Production();
Consumer consumer = new Consumer(pen);
Producer producer = new Producer(pen);
new Thread(producer).start(); // 开启生产者线程
new Thread(consumer).start(); // 开启消费者线程
Thread.sleep(10000);
pen.setContinueProduce(false); // 10s后停止生产该类型的笔
}
}
运行结果