JUC学习笔记-08-阻塞队列BlockingQueue

阻塞队列BlockingQueue的概念

队列:排队 特性:先进先出 FIFO
阻塞:必须要阻塞、不得不阻塞
阻塞队列的应用场景:多线程并发处理,线程池

在这里插入图片描述

BlockingQueue与List的千丝万缕

在这里插入图片描述

List的实现类和BlockingQueue的实现类

  • List的实现类
    • ArrayList
    • LinkedList
  • BlockingQueue的实现类
    • ArrayBlockingQueue:数组实现的阻塞队列
    • LinkedBlockingQueue:链表实现的阻塞队列
    • SynchronousQueue:同步队列

ArrayBlockingQueue的四组API

ArrayBlockingQueue是BlockingQueue的实现类
1、ArrayBlockingQueue 是一个有限的blocking queue,由数组支持。
2、这个队列排列元素FIFO(先进先出)。
3、队列的固定大小创建后,容量无法更改。

四组API是以插入元素,移除元素和检查队首元素的基础上建立的,分别是:
抛出异常、返回特殊值、超时退出、一直等待

方法抛出异常返回特殊值超时退出一直等待
插入addofferoffer(e, timeout, unit)put ()
移除removepollpoll(timeout, unit)take()
检查队首elementpeek

1、抛出异常

public class ArrayBlockingQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        //创建大小为3的阻塞队列
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(3);
        //取不到值或者队列已满无法添加抛出异常
        //queueApiException(arrayBlockingQueue);
        //取不到值返回null或者队列已满无法添加返回false值
        //queueApiNotException(arrayBlockingQueue);
        //取不到值或者队列已满无法添加,若到超出指定时间则退出
        //queueApiTimeOutExit(arrayBlockingQueue);
        //取不到值或者队列已满无法添加一直阻塞等待下去直到能获取到值或者能添加值
        //queueApiWaitingAlone(arrayBlockingQueue);
    }
    public static void queueApiException(ArrayBlockingQueue arrayBlockingQueue){
        arrayBlockingQueue.add("a");
        arrayBlockingQueue.add("b");
        arrayBlockingQueue.add("c");
        //arrayBlockingQueue.add("d"); //java.lang.IllegalStateException: Queue full
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());
        //取出元素,队列为空抛出异常java.util.NoSuchElementException
        //System.out.println(arrayBlockingQueue.remove());
        //检查队首元素peek方法,没有元素抛出异常java.util.NoSuchElementException
        //arrayBlockingQueue.element();
    }
}

2、返回特殊值

	public static void queueApiNotException(ArrayBlockingQueue arrayBlockingQueue){
        System.out.println(arrayBlockingQueue.offer("a"));
        System.out.println(arrayBlockingQueue.offer("b"));
        System.out.println(arrayBlockingQueue.offer("c"));
        //队列已满无法添加返回false值
        //System.out.println(arrayBlockingQueue.offer("d")); //false 我们通常不希望代码报错!这时候就使用offer

        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        //队列为空无法获取返回null
        // System.out.println(arrayBlockingQueue.poll());


        //System.out.println(arrayBlockingQueue.peek()); //null
    }

3、超时等待

    /**
     *  @description:设置等待时间,超时就退出
     *  @author yangxj
     *  @date 2020/2/23 17:54
     */
    public static void queueApiTimeOutExit(ArrayBlockingQueue arrayBlockingQueue) throws InterruptedException {
        System.out.println(arrayBlockingQueue.offer("a"));
        System.out.println(arrayBlockingQueue.offer("b"));
        System.out.println(arrayBlockingQueue.offer("c"));
        // 超过3秒就不等待了,返回false
        //System.out.println(arrayBlockingQueue.offer("d",3, TimeUnit.SECONDS));

        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        // 超过3秒就不等待了,返回false
        //System.out.println(arrayBlockingQueue.poll(3,TimeUnit.SECONDS));//返回null
    }

4、一直等待

    /**
     *  @description:一直等待阻塞
     *  @author yangxj
     *  @date 2020/2/23 17:54
     */
    public static void queueApiWaitingAlone(ArrayBlockingQueue arrayBlockingQueue) {
        try {
            arrayBlockingQueue.put("a");
            arrayBlockingQueue.put("b");
            arrayBlockingQueue.put("c");
            //一直等待
            //arrayBlockingQueue.put("d");

            System.out.println(arrayBlockingQueue.take());
            System.out.println(arrayBlockingQueue.take());
            System.out.println(arrayBlockingQueue.take());
            //一直等待
            //System.out.println(arrayBlockingQueue.take());//阻塞等待拿出元素
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

SynchronousQueue同步队列

SynchronousQueue是BlockingQueue的实现类,那它和ArrayBlockingQueue有什么区别呢?
SynchronousQueue是不能存储元素的,存入一个必须取出一个,否则无法添加元素,我们可以将其理解为数据块大小为1的ArrayBlockingQueue当中一种阻塞的put和take

/**
 * 同步队列SynchronousQueue
 * 1、不存储元素,队列是空的
 * 2、每一个 put 操作。必须等待一个take。否则无法继续添加元素!
 * 3、可以将SynchronousQueue理解为只有一个数据大小的ArrayBlockingQueue当中的一直阻塞put和take。
 */
public class SynchronousQueueDemo {

    public static void main(String[] args) {
        SynchronousQueue synchronousQueue = new SynchronousQueue();

        //添加元素线程
        new Thread(() -> {
            try {

                synchronousQueue.put("1");
                System.out.println(Thread.currentThread().getName() + ":put 1");

                synchronousQueue.put("2");
                System.out.println(Thread.currentThread().getName() + ":put 2");

                synchronousQueue.put("3");
                System.out.println(Thread.currentThread().getName() + ":put 3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"put element").start();

        //读取元素线程
        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+synchronousQueue.take());

                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+synchronousQueue.take());

                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+synchronousQueue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"get element").start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值