阻塞队列(BlockingQueue)

发布时间 2024-01-09 16:11:21作者: C_C_菜园

阻塞队列(BlockingQueue)

  • 实现了:BlockingQueue
  • JDK提供的七个阻塞队列
    image

一、特点

1、JDK提供的七个阻塞队列简介

①. ArrayBlockingQueue

有界 阻塞队列——必须指定大小——数组

②. LinkedBlockingQueue

有界 阻塞队列——默认大小:Integer.MAX_VALUE最大值——链表

③. LinkedTransferQueue

无界 阻塞队列——链表

④. PriorityBlockingQueue

无界 阻塞队列——支持优先级排序

⑤. DelayQueue

无界 阻塞队列——使用优先级队列实现的

⑥. SynchronousQueue

不存储元素 的阻塞队列

⑦. LinkedBlockingDeque

双端 阻塞队列——链表

2、其他特点

  • 阻塞队列默认情况下是FIFO(先进先出)PriorityBlockingQueue可以设置优先级出队列
  • BlockingQueue 不接受 null 元素。试图 add、put 或 offer 一个 null 元素时,某些实现会抛出 NullPointerException。null 被用作指示 poll 操作失败的警戒值。
  • BlockingQueue 实现是线程安全

二、阻塞队列的方法

  • e 表示插入到队列的元素

1、插入元素

描述 抛出异常 一直阻塞 返回特殊的值 超时退出
插入数据 add(e) put(e) offer(e)
推荐
offer(e, time, unit)
推荐
插入成功 返回true 无返回值 返回true 返回true
插入失败
(队列满)
抛异常 一直阻塞,直到插入元素 返回false 等10秒(假如设置的10s)
然后放弃插入返回false
可用于控制添加元素的速度

2、获取元素——并移除队列的头元素

描述 抛出异常 一直阻塞 返回特殊的值 超时退出
获取元素 remove() take() poll() poll(time, unit)
获取成功 返回元素 返回元素 返回元素 返回元素
获取失败
(队列空)
抛异常 一直阻塞,直到获取到元素 返回null 等10秒(假如设置的10s)
然后null
可用于控制消费的速度

3、获取元素——不移除队列的元素

描述 抛出异常 返回特殊的值
获取元素 element() peek()
获取成功 返回元素 返回元素
获取失败
(队列空)
抛异常 返回null

4、测试

  • 自己去测
package com.cc.testproject.utils;

import java.time.LocalDateTime;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.PriorityBlockingQueue;

/**
 * <p>存放队列</p>
 *
 * @author --
 * @since 2024/1/9
 */
public class QzJobDwSchTask {

    //有界阻塞队列——FIFO(先进先出)——必须指定大小——数组
    private static final ArrayBlockingQueue<String> QUEUE1 = new ArrayBlockingQueue<>(1);
    //有界阻塞队列——FIFO(先进先出)——默认大小:int最大值——链表
    private static final LinkedBlockingQueue <String> QUEUE2 = new LinkedBlockingQueue<>();
    //无界阻塞队列——FIFO(先进先出)——无限大——链表
    private static final LinkedTransferQueue <String> QUEUE3 = new LinkedTransferQueue<>();

    public static void main(String[] args) throws InterruptedException {

        boolean offer = QUEUE1.offer("1");
        System.out.println("第1次添加:" + offer + "-时间:" + LocalDateTime.now());
        boolean offer1 = QUEUE1.offer("2");
        System.out.println("第2次添加:" + offer1 + "-时间:" + LocalDateTime.now());

        System.out.println(QUEUE1.take());

//        System.out.println(QUEUE1.element());
        System.out.println(QUEUE1.peek());
        System.out.println(QUEUE1);

//        System.out.println(QUEUE1.poll(5, TimeUnit.SECONDS));
//        System.out.println(QUEUE1.poll());
//        System.out.println(QUEUE1.remove());
//        System.out.println(QUEUE1.take());

//        System.out.println(QUEUE1.remove());
//        System.out.println(QUEUE1.remove());
//        System.out.println(QUEUE1.take());
//        System.out.println(QUEUE1.take());
//        System.out.println(QUEUE1.poll());
//        System.out.println(QUEUE1.poll(5, TimeUnit.SECONDS));

        //如队列满:等10秒,然后放弃插入,返回false
//        boolean offer = QUEUE1.offer("1", 10, TimeUnit.SECONDS);
//        System.out.println("第1次添加:" + offer + "-时间:" + LocalDateTime.now());
//        boolean offer1 = QUEUE1.offer("2", 10, TimeUnit.SECONDS);
//        System.out.println("第2次添加:" + offer1 + "-时间:" + LocalDateTime.now());
//
//        System.out.println("添加完成:" + QUEUE1);

        // 如队列满:抛异常
//        boolean add1 = QUEUE1.add("1");
//        System.out.println("第1次添加:" + add1);
//        boolean add2 = QUEUE1.add("2");
//        System.out.println("第2次添加:" + add2);

        //如队列满:一直等
//        QUEUE1.put("1");
//        System.out.println("第1次添加:" + LocalDateTime.now());
//        QUEUE1.put("2");
//        System.out.println("第2次添加:" + LocalDateTime.now());
    }
}

三、使用场景、个人理解

1、使用场景

  • 需要顺序执行,且是耗时操作,可用来装用户的请求
  • 一般用来存放任务

2、个人理解

  • 阻塞队列之所以叫阻塞队列,是因为它可以在添加或者获取元素的时候阻塞添加或获取的线程

四、参考:
1、http://t.csdnimg.cn/BAAcc这里
2、http://t.csdnimg.cn/sGtuA这里
3、http://t.csdnimg.cn/fA8T7这里