public class ProdConsumer_BlockQueueDemo {
public static void main(String[] args) {
MyShare myShare = new MyShare(new ArrayBlockingQueue<>(10));
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName()+"生产线程启动");
myShare.myProd();
} catch (InterruptedException e) {
e.printStackTrace();
}
},"1").start();
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName()+"消费线程启动");
myShare.myConsumer();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
},"2").start();
try {
TimeUnit.SECONDS.sleep(6);
} catch (InterruptedException e) {
e.printStackTrace();
}
myShare.stop();
System.out.println("停止生产者消费者模式");
}
static class MyShare{
private volatile boolean FLAG = true;//默认开启,进行生产+消费
private AtomicInteger atomicInteger = new AtomicInteger();
BlockingQueue<String> bolckingQueue = null;
public MyShare(BlockingQueue<String> bolckingQueue) {
this.bolckingQueue = bolckingQueue;
System.out.println(bolckingQueue.getClass().getName());
}
public void myProd() throws InterruptedException {
String data = null;
boolean retValue;
while (FLAG){
data = atomicInteger.incrementAndGet()+"";
retValue = bolckingQueue.offer(data,2L,TimeUnit.SECONDS);
if (retValue){
System.out.println(Thread.currentThread().getName()+"生产"+data+"成功");
}else{
System.out.println(Thread.currentThread().getName()+"生产"+data+"失败");
}
TimeUnit.SECONDS.sleep(1);//1s生产一个
}
System.out.println(Thread.currentThread().getName()+"停止生产");
}
public void myConsumer() throws Exception {
String result = null;
while (FLAG) {
result = bolckingQueue.poll(2L, TimeUnit.SECONDS);
if (result == null || "".equalsIgnoreCase(result)) {
FLAG = false;
System.out.println("两秒没有生产了,退出消费");
return;
}
System.out.println(Thread.currentThread().getName() + "消费" + result + "成功");
}
}
public void stop() {
this.FLAG = false;
}
}
}
结果1生产线程启动
2消费线程启动
1生产1成功
2消费1成功
1生产2成功
2消费2成功
1生产3成功
2消费3成功
1生产4成功
2消费4成功
1生产5成功
2消费5成功
1生产6成功
2消费6成功
停止生产者消费者模式
1停止生产
两秒没有生产了,退出消费
实验中用volatile修饰flag,用来及时通知别的线程状态的改变,即开启或者停止生产-消费模式,用atomicInteger计数保证了数据的原子性,对比一般的生产者消费者模式,用阻塞队列来实现的话我们就不需要关心什么时候阻塞,什么时候唤醒线程