阻塞队列(BlockingQueue)

阻塞队列(BlockingQueue)

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

一、特点

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、推荐使用

  • 一般情况下 offer() 和 poll() 方法配合使用

程序中常用的是 offer() 和 poll() 方法,因为这两个方法比较友好,不会报错

  • put() 和 take() 阻塞方法配合使用
  • add() 和 remove() 方法会配合使用

5、测试

  • 自己去测
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 Task01 {

    //有界阻塞队列——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、个人理解

  • 阻塞队列之所以叫阻塞队列,是因为它可以在添加或者获取元素的时候阻塞添加或获取的线程。直到线程达到自己的目的。
  • 阻塞队列之所以被称为阻塞队列,是因为当队列已满时,尝试向队列中添加元素的线程会被阻塞,直到队列有空间为止;当队列为空时,尝试从队列中获取元素的线程会被阻塞,直到队列中有元素为止。这种行为可以确保线程安全地在队列中添加或获取元素。

四、参考:

热门相关:恶明   墨桑   布衣官道   重生隐婚:Hi,高冷权少!   盛世娇宠之名门闺香