想用BlockingQueue实现生产者消费者问题
这里用ArrayBlockingQueue做阻塞队列,用队列长度设定库存量
用AtomicInteger存库存数量number
用flag控制生产线
还是会出现以下问题
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 共享资源
*/
class Share {
private volatile boolean flag = true; //控制工作状态:t工作; f停止
private AtomicInteger number = new AtomicInteger();
//阻塞队列:相当于库存容器
private BlockingQueue<Integer> blockingQueue = null;
//开闭原则,容器的实现方式可以自定义,通过构造方法传实现类
public Share(BlockingQueue<Integer> blockingQueue) {
this.blockingQueue = blockingQueue;
System.out.println("实现类:" + blockingQueue.getClass().getName());
}
//生产
public void myProd() throws InterruptedException {
Integer date = null;
boolean retValue;//记录这次插入操作是否成功,提取
while (flag) {
//生产,增加库存
date = number.incrementAndGet();
//向阻塞队列插入,并返回是否成功
retValue = blockingQueue.offer(date, 2, TimeUnit.SECONDS);
if (retValue) {
System.out.println(Thread.currentThread().getName() + "\t插入" + date + "成功");
} else {
System.out.println(Thread.currentThread().getName() + "\t插入" + date + "失败");
}
//TimeUnit.SECONDS.sleep(1);
}
System.out.println(Thread.currentThread().getName() + "停止生产");
}
//消费
public void myConsumer() throws InterruptedException {
Integer result;
//消费者可以一直去购买, 从blockingQueue拿产品
while (true) {
result = blockingQueue.poll(2, TimeUnit.SECONDS);
//值空了,没了库存,停止消费,等到有货再消费
if (result == null || result == 0) {
flag = false;
System.out.println(Thread.currentThread().getName() + "\t 超过两秒没有取出产品,消费退出");
return;
}
System.out.println(Thread.currentThread().getName() + "\t 取出产品" + result + "成功");
}
}
//控制生产线
public void stop() {
this.flag = false;
}
}
public class Demo3 {
public static void main(String[] args) {
Share share = new Share(new ArrayBlockingQueue<>(5));
new Thread(() -> {
try {
share.myProd();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "生产者").start();
new Thread(() -> {
try {
share.myConsumer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "消费者").start();
//等待几秒后,暂停生产
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("时间到,叫停生产");
share.stop();
}
}