用阻塞队列来写,就不需要程序员来关心什么时候阻塞线程await,什么时候唤醒线程notify()。
类似消息中间件
package JUC;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 3.0版生产者消费者(不用程序员控制,用阻塞队列)
*/
class MyResource{
private volatile boolean FLAG = true; //默认打开,进行生产+消费
private AtomicInteger atomicInteger = new AtomicInteger(1);
//BlockingQueue如果要适配所有类的话,要传接口,不能传类
BlockingQueue<String> blockingQueue = null;
public MyResource(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
System.out.println(blockingQueue.getClass().getName()); //显示传的什么类
}
public void myProducer() throws Exception{
String data = null;
boolean retValue;
while(FLAG){
data = atomicInteger.getAndIncrement()+"";
retValue = blockingQueue.offer(data,2L, TimeUnit.SECONDS);
if (retValue){
System.out.println(Thread.currentThread().getName()+"\t 插入队列"+data+"成功");
}else {
System.out.println(Thread.currentThread().getName()+"\t 插入队列"+data+"失败");
}
TimeUnit.SECONDS.sleep(1);
}
System.out.println(Thread.currentThread().getName()+"\t大老板叫停,表示FLAG=false,生产动作结束");
}
public void myConsumer() throws Exception{
String result = null;
while (FLAG){
result = blockingQueue.poll(2L,TimeUnit.SECONDS);
if (result == null || result.equalsIgnoreCase("")){
FLAG = false;
System.out.println(Thread.currentThread().getName()+"\t超过2秒钟没有取到蛋糕,消费退出");
return;
}
System.out.println(Thread.currentThread().getName()+"\t消费队列"+result+"成功");
}
}
public void stop() throws Exception{
this.FLAG = false;
}
}
public class ProdConsumer_BlockQueueDemo {
public static void main(String[] args) {
MyResource myResource = new MyResource(new ArrayBlockingQueue<>(3));
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t生产线程启动");
try {
myResource.myProducer();
} catch (Exception e) {
e.printStackTrace();
}
},"producer").start();
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t消费线程启动");
System.out.println();
System.out.println();
try {
myResource.myConsumer();
System.out.println();
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
},"consumer").start();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println();
System.out.println();
System.out.println("5秒钟时间到,大老板main线程叫停,游戏结束!");
try {
myResource.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}