大家最开始学多线程的时候一定学过生产者与消费者,比如生产包子和买包子。
传统老版本1.0
入门的时候是通过synchronized来锁住线程,用wait来进行等待,用notify来唤醒。
Lock锁控制2.0
但是这套方法已经过时,自从有了JUC以后,就可以将其升级为更灵活的版本2.0
阻塞队列3.0
当然有阻塞队列后就更简单了,当队列中有值时,才能取,这不就是完美的解决方法吗!而且简单粗暴,无需判断与加锁。
一般用offer的三参构造,能进行灵活的锁定与判断操作
boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;
用poll的双参构造,避免一直等待或直接抛异常,有一定的缓冲时间
E poll(long timeout, TimeUnit unit)
throws InterruptedException;
接下来上代码
class MyShareData{
private AtomicInteger atomicInteger=new AtomicInteger();//保证原子性
private volatile boolean Flag=true;//volatile保证可见性
private BlockingQueue<String> blockingQueue;//用接口可接收7种实现类的任意一种,更加灵活!
public MyShareData(BlockingQueue blockingQueue) {
this.blockingQueue = blockingQueue;
}
public void provider() throws InterruptedException {
String data="";
boolean returnValue;
while (Flag){//多了一个判断机制,可以手动的退出流程
data=atomicInteger.incrementAndGet()+"";
returnValue=blockingQueue.offer(data,1, TimeUnit.SECONDS);
if (returnValue){
System.out.println(Thread.currentThread().getName()+"蛋糕"+atomicInteger+"生产成功");
}else {
System.out.println(Thread.currentThread().getName()+"蛋糕"+atomicInteger+"生产失败");
}
TimeUnit.SECONDS.sleep(1);
}
System.out.println("大老板叫停,不用干了");
}
public void consumer() throws InterruptedException {
String result="";
while (Flag){
result= blockingQueue.poll(2, TimeUnit.SECONDS);
if (null==result||result.equals("")){
System.out.println(Thread.currentThread().getName()+"超过2秒钟没取到蛋糕,消费退出");
Flag=false;
return;
}
System.out.println(Thread.currentThread().getName()+"獲取成功"+result);
}
}
public void stop(){
Flag=false;
}
}
public class BlockQueueDemo {
public static void main(String[] args) {
MyShareData myShareData = new MyShareData(new ArrayBlockingQueue(1));
new Thread(()->{
try {
myShareData.provider();
} catch (InterruptedException e) {
e.printStackTrace();
}
},"AA").start();
new Thread(()->{
try {
myShareData.consumer();
} catch (InterruptedException e) {
e.printStackTrace();
}
},"BB").start();
try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}
myShareData.stop();
}
}