BlockingQueue阻塞队列
BlockingQueue
1. 阻塞队列
2. 为什么?阻塞队列有什么好处:
3.架构介绍
4. BlockingQueue种类分类
5. BlockingQueue核心方法
工作中用超时offer poll这一组
/**
* 阻塞队列
*
* 1 两个数据结构:栈/队列
* 1.1 栈 后进先出
* 1.2 队列 先进先出
* 1.3 总结
*
* 2 阻塞队列
* 2.1 阻塞 必须要阻塞/不得不阻塞
*
* 3 how
*/
public class BlockingQueueDemo {
public static void main(String[] args) {
//List list = new ArrayList();
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
System.out.println(blockingQueue.add("d"));
}
}
输出结果
当队列满了再添加会抛出java.lang.IllegalStateException: Queue full
异常信息
true
true
true
Exception in thread "main" java.lang.IllegalStateException: Queue full
at java.util.AbstractQueue.add(AbstractQueue.java:98)
at java.util.concurrent.ArrayBlockingQueue.add(ArrayBlockingQueue.java:312)
at wj.leslie.day3.BlockingQueueDemo.main(BlockingQueueDemo.java:28)
public class BlockingQueueDemo {
public static void main(String[] args) {
//List list = new ArrayList();
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
// System.out.println(blockingQueue.add("d"));
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
}
}
输出结果
当队列为空 ,再取数据会抛出java.util.NoSuchElementException
异常
true
true
true
a
b
c
Exception in thread "main" java.util.NoSuchElementException
at java.util.AbstractQueue.remove(AbstractQueue.java:117)
at wj.leslie.day3.BlockingQueueDemo.main(BlockingQueueDemo.java:33)
public class BlockingQueueDemo {
public static void main(String[] args) {
//List list = new ArrayList();
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d"));
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
}
}
输出结果
true
true
true
false
a
b
c
null
public class BlockingQueueDemo {
public static void main(String[] args) throws InterruptedException {
//List list = new ArrayList();
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
blockingQueue.put("d");
}
}
public class BlockingQueueDemo {
public static void main(String[] args) throws InterruptedException {
//List list = new ArrayList();
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
// blockingQueue.put("d");
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
}
}
public class BlockingQueueDemo {
public static void main(String[] args) throws InterruptedException {
//List list = new ArrayList();
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d",3L,TimeUnit.SECONDS));
}
}
输出结果
true
true
true
//3秒后输出false
false
SynchronousQueue
public class SynchronousQueueDemo {
public static void main(String[] args) {
BlockingQueue<String> blockingQueue = new SynchronousQueue<>();
new Thread(()->{
try{
System.out.println(Thread.currentThread().getName()+"\t put 1");
blockingQueue.put("1");
System.out.println(Thread.currentThread().getName()+"\t put 2");
blockingQueue.put("2");
System.out.println(Thread.currentThread().getName()+"\t put 3");
blockingQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"AA").start();
new Thread(()->{
try{
//暂停一会线程
try { TimeUnit.SECONDS.sleep(5); }catch (InterruptedException e){ e.printStackTrace(); }
System.out.println(Thread.currentThread().getName()+"\t "+blockingQueue.take());
try { TimeUnit.SECONDS.sleep(5); }catch (InterruptedException e){ e.printStackTrace(); }
System.out.println(Thread.currentThread().getName()+"\t "+blockingQueue.take());
try { TimeUnit.SECONDS.sleep(5); }catch (InterruptedException e){ e.printStackTrace(); }
System.out.println(Thread.currentThread().getName()+"\t "+blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"BB").start();
}
}
6.BlockingQueue用在哪里
生产者消费者模式
1. 传统版
/**
* @Author leslie
* @Date 2021/9/11
* 题目:一个初始值为零的遍历,两个线程对其交替操作,一个加1一个减1,来5轮
* 1 线程 操作 资源类
* 2 判断 干活 通知
* 3 防止虚假唤醒机制
*/
class ShareDate{//资源类
private int number = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void increment() throws Exception{
lock.lock();
try{
//1 判断
while(number!=0){
//等待,不能生产
condition.await();
}
//2 干活
number++;
System.out.println(Thread.currentThread().getName()+"\t "+number);
//3.通知唤醒
condition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void decrement() throws Exception{
lock.lock();
try{
//1 判断
while(number==0){
//等待,不能生产
condition.await();
}
//2 干活
number--;
System.out.println(Thread.currentThread().getName()+"\t "+number);
//3.通知唤醒
condition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
public class ProdConsunmer_TraditionDemo {
public static void main(String[] args) {
ShareDate shareDate = new ShareDate();
new Thread(()->{
for (int i = 1; i <=5 ; i++) {
try {
shareDate.increment();
}catch (Exception e){
e.printStackTrace();
}
}
},"AA").start();
new Thread(()->{
for (int i = 1; i <=5 ; i++) {
try {
shareDate.decrement();
}catch (Exception e){
e.printStackTrace();
}
}
},"BB").start();
}
}
2. 阻塞队列版
/**
* @Author leslie
* @Date 2021/9/11
* volatile/CAS/AtomicInteger/BlockingQueue/线程交互/原子引用
*/
class MyResource{
private volatile boolean FALG = true;//默认开始,进行生产+消费
private AtomicInteger atomicInteger = new AtomicInteger();
BlockingQueue<String> blockingQueue = null;
public MyResource(BlockingQueue<String> blockingQueue){
this.blockingQueue = blockingQueue;
System.out.println(blockingQueue.getClass().getName());
}
public void myProd() throws Exception{
String data = null;
boolean retValue;
while (FALG){
data = atomicInteger.incrementAndGet()+"";
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 (FALG){
result = blockingQueue.poll(2L,TimeUnit.SECONDS);
if(null == result || result.equalsIgnoreCase("")){
FALG = false;
System.out.println(Thread.currentThread().getName()+"\t 超过两秒钟没有取到蛋糕,消费退出");
return;
}
System.out.println(Thread.currentThread().getName()+"\t 消费队列蛋糕"+result+"成功");
}
}
public void stop() throws Exception{
this.FALG = false;
}
}
public class ProdConsunmer_BlockQueueDemo {
public static void main(String[] args) throws Exception {
MyResource myResource = new MyResource(new ArrayBlockingQueue<>(10));
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t 生产线程启动");
try {
myResource.myProd();
} catch (Exception e) {
e.printStackTrace();
}
},"Prod").start();
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t 消费线程启动");
System.out.println();
System.out.println();
try {
myResource.myConsumer();
} 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();
System.out.println("5秒钟时间到,大老板main线程叫停,活动结束");
myResource.stop();
}
}