首页 > 编程语言 >【Java】阻塞队列

【Java】阻塞队列

时间:2023-01-26 15:04:38浏览次数:38  
标签:Java 队列 transfer 元素 阻塞 线程 方法


【Java】阻塞队列

什么是阻塞队列?

阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这2个附加的操作支持阻塞的插入和移除方法。

  • 支持阻塞的插入方法:当队列满时,队列会阻塞插入元素的线程,直到队列不满;
  • 支持阻塞的移除方法:当队列为空时,获取元素的线程会等待队列变为非空。

阻塞队列常用于生产者和消费者的场景,生产者是向队列里添加元素的线程,消费者是从队列里取元素的线程。阻塞队列就是生产者用来存放元素、消费者用来获取元素的容器。

在阻塞队列不可用时,这两个附加操作提供了4种处理方式,如下所示:

操作

抛异常

特定值

阻塞

超时

插入

add(o)

offer(o)

put(o)

offer(o, timeout, timeunit)

移除

remove(o)

poll(o)

take(o)

poll(timeout, timeunit)

检查

element(o)

peek(o)

这四类方法分别对应的是:

  • ThrowsException:如果操作不能马上进行,则抛出异常;
  • Special Value:如果操作不能马上进行,将会返回一个特殊的值,一般是true或者false;
  • Blocks:如果操作不能马上进行,操作会被阻塞;
  • TimesOut:如果操作不能马上进行,操作会被阻塞指定的时间,如果指定时间没执行,则返回一个特殊值,一般是true或者false。

JDK提供的阻塞队列

【Java】阻塞队列_java

ArrayBlockingQueue 数组结构组成的有界阻塞队列(需要指定队列的大小):此队列按照先进先出(FIFO)的原则对元素进行排序,但是默认情况下不保证线程公平的访问队列,即如果队列满了,那么被阻塞在外面的线程对队列访问的顺序是不能保证线程公平(即先阻塞,先插入)的;

LinkedBlockingQueue一个由链表结构组成的有界阻塞队列:此队列的默认和最大长度为​​Integer.MAX_VALUE​​。此队列按照先进先出的原则对元素进行排序;

PriorityBlockingQueue支持优先级的无界阻塞队列:默认情况下元素采取自然顺序升序排列。也可以自定义类实现​​compareTo()​​​方法来指定元素排序规则,或者初始化PriorityBlockingQueue时,指定构造参数​​Comparator​​来进行排序。需要注意的是不能保证同优先级元素的顺序;

DelayQueue支持延时获取元素的无界阻塞队列:即可以指定多久才能从队列中获取当前元素,队列使用PriorityBlockingQueue来实现。队列中的元素必须实现Delayed接口,在创建元素时可以指定多久才能从队列中获取当前元素。只有在延迟期满时才能从队列中提取元素;

DelayQueue运用在以下应用场景:

  • 缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从DelayQueue中获取元素时,表示缓存有效期到了;
  • 任务超时处理:比如下单后15分钟内未付款,自动关闭订单。

SynchronousQueue是一个不存储元素的阻塞队列:每一个put操作必须等待一个take操作,否则不能继续添加元素;

LinkedTransferQueue由链表结构组成的无界阻塞TransferQueue队列:相对于其他阻塞队列,LinkedTransferQueue多了tryTransfer和transfer方法;

  • ​transfer​​​方法
    如果当前有消费者正在等待接收元素(消费者使用take()方法或带时间限制的poll()方法时),transfer方法可以把生产者传入的元素立刻transfer(传输)给消费者。如果没有消费者在等待接收元素,transfer方法会将元素存放在队列的tail节点,并等到该元素被消费者了才返回。
  • ​tryTransfer​​​方法
    tryTransfer方法时用来试探生产者传入的元素是否能直接传给消费者。如果没有消费者等待接收元素,则返回fasle。和transfer方法的区别是tryTransfer方法无论消费者是否接收,方法立即返回,而transfer方法是必须等到消费者消费了才返回。

LinkedBlockingDeque链表结构的双向阻塞队列:优势在于多线程入队时,减少一半的竞争。

线程池中使用阻塞队列

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}


标签:Java,队列,transfer,元素,阻塞,线程,方法
From: https://blog.51cto.com/u_15719567/6023548

相关文章

  • JavaScript学习笔记—Date
    在JS中所有的和时间相关的数据都由Date对象来表示对象的方法(1)getFullYear()返回当前日期的年份(4位)(2)getMonth()返回当前日期的月份(0-11)(3)getDate()返回当前日期的几......
  • JavaScript学习笔记—Math
    工具类为我们提供了数学运算相关的一些常量和方法常量(1)Math.PI圆周率方法(1)Math.abs()求一个数的绝对值(2)Math.min()求多个值中的最小值(3)Math.max()求多个值中的......
  • Java源码解析 Collection<E>
    位置: java.util.Collection<E>interface用途:参数:<E>Iterable<E>子类:接口:方法   int size();  返回这......
  • Java JDK安装文件提取为绿色版(免安装版)
    前言在服务端部署Java项目时,可能会根据项目的环境考虑使用不同的JDK版本,在使用时根据不同项目切换jdk版本很不方便。另外,安装的jdk会自动安装jdk_update,但是我又不想让jdk......
  • LESSON THREE:Java入门环境搭建
    Java入门环境搭建Java如何诞生改进了c与c++的一些难点;1995年诞生;三大版本:JavaSE:标准版(桌面程序、控制台开发、简单游戏...)JavaME:嵌入式开发JavaEE:E企业级开发(web......
  • 【学懂Java】(六)常用类
    一.包装类1.概念包装类是将基本类型封装到一个类中,包含属性和方法,方便对象操作包装类位于java.lang包中2.转换包装类与基本数据类型包装类是将基本数据类型封装成一个类,包......
  • 你知道这个提高 Java 单元测试效率的 IDEA 插件吗
    前言2023年我们公司主抓代码质量,所以单元测试必不可少,而且都写到了年底的绩效目标中了。在考虑如何达成这个目标的过程中,我发现了一个关于单元测试的IDEA插件——SquareTe......
  • C++ 和 Java 的区别(A C++ programmer's perspective)
    C++开发,周末看了2天Java教程,直接上手写Java。说下自己最明显的感受,用的不多,理解不一定对:【JVM】Java编译+解释,运行在JVM,跨平台移植方便,但执行速度/效率比C++低......
  • 读Java8函数式编程笔记01_Lambda表达式
    1. Java8函数式编程1.1. 没有单子1.2. 没有语言层面的惰性求值1.3. 没有为不可变性提供额外支持1.4. 集合类可以拥有一些额外的方法:default方法2. 现实世界中......
  • 用两个栈实现一个队列
    #codeclassQueue{#stack1=[]#stack2=[]add(value){this.#stack1.push(value)returnthis.#stack1.length}delete(){......