线程池的核心——BlockingQueue

前言

本篇文章会介绍BlockingQueue的概念。

BlockingQueue是java线程池的核心。无论是在面试还是工作中,都是必知必会的知识点。

BlockingQueue的名字就完美概括了这个接口的特点,Queue 是BlockingQueue的父接口,说明它本质还是一个队列。Blocking意为阻塞,说明BlockingQueue相对于普通队列,新增了阻塞的特性。

本文会从BlockingQueue的父接口Queue开始聊起,包括Queue在java 容器中的定位以及API等等。然后介绍BlockingQueue相比于Queue新增出来的方法。最后会介绍几个BlockingQueue接口的具体实现类的特点和具体用法。

从父接口Queue开始聊起

Queue接口是Java容器大家庭中的一员,具体的定位如下图所示:

在这里插入图片描述
Queue自从java 1.5之后,成为接口Collection下的一员,Queue与ListSet最大的区别就在于,Queue是专门为高并发存在的。

除去基本的Collection自带的方法,Queue额外提供了增、删、查的方法。每一种操作又会有两种具体的实现方法,区别在于操作失败时,是抛出错误还是返回某个特定值。

下面对这些方法做一个总结

抛出异常 返回特定值
add() offer() – 返回false
remove() poll() – 返回null
element() peek() – 返回null

注意,其中的查操作和删操作,只能操作队列的头节点,并不能对队列中间的节点执行操作。

BlockingQueue接口及具体实现类

BlockingQueue接口API

由于BlockingQueue是Queue的子接口,所以上面的方法都包含在BlockingQueue中。

而BlockingQueue与Queue的主要区别,在于它新增了阻塞方法

什么是阻塞方法呢?简而言之,是当这个操作暂时没法完成的时候,会阻塞住当前线程,直到这个操作完成或者超时。

比如向队列中新增一个元素,如果队列已经满了,这个新增操作就会阻塞住线程,接下来根据选择的具体方法的不同,要么会一直等到队列中有了空位,要么会等超时后返回某个特定值。

BlockingQueue,相对于Queue,新增了两种增加元素和删除元素的阻塞方法,而这些阻塞方法也分成两种类型,一种是一直等待,一种是超时返回特定值。

抛出异常 返回特定值 阻塞等待 超时返回
add() offer() – 返回false put() offer(e, time, unit) – 返回false
remove() poll() – 返回null take() poll(time, unit) – 返回null
element() peek() – 返回null 不存在 不存在

表中没有标红的方法是继承自Queue接口中的方法,而标红的则是BlockingQueue新增的方法。

具体实现类

BlockingQueue本身也只是个接口,真正发挥作用的是它的具体实现类。

而它的实现类还可以进一步的分类:

如果队列中的元素是按照先进先出排序的,那么可以用LinkedBlockingQueueArrayBlockingQueue

如果要自己实现排序原则,就需要PriorityBlockingQueueDelayQueue

如果要实现添加元素的线程继续追踪该元素直到该元素被取出,就需要SynchronousQueueTransferQueue

LinkedBlockingQueue 和 ArrayBlockingQueue

这两种具体实现的区别就在于底层的数据结构,一个使用链表而另一个使用数组。

从而也就导致了容量上的不同,理论上LinkedBlockingQueue的容量理论上是无限的,而ArrayBlockingQueue的容量受底层的数组限制。

从两者的构造函数就能看出上述区别,ArrayBlockingQueue的构造函数要求必须声明容量上限,而LinkedBlockingQueue可以不声明上限,默认是Integer.MAX_VALUE的值。

PriorityBlockingQueue 和 DelayQueue

Queue本身是先进先出的队列,各个元素在队列里的顺序是按照加入到容器的先后顺序。

但是PriorityBlockingQueue和DelayQueue就可以自定义元素在队列中的排序原则。

PriorityBlockingQueue默认使用元素的compareTo方法,按从小到大的顺序排列元素。调用take()会获取到队列中最小的元素。

也可以在调用构造函数时声明自定义的Comparator,队列中的元素会按照Comparator指定的规则进行排序。

DelayQueue要求队列中的所有的元素都实现Delayed接口,这些元素必须实现的方法是getDelay(TimeUnit unit)compareTo()方法。

元素在队列中按照compareTo指定的顺序排列。但是,将队列元素取出的操作还依赖于这个元素是否已经过期。这里过期的含义是getDelay()方法返回0或者负数。

比如下面这段代码:

public class BlockingQueueDemo {
   
    public static void main(
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值