Java并发编程之BlockingQueue

引言: 阻塞队列 (BlockingQueue)是Java util.concurrent包下重要的数据结构,BlockingQueue提供了线程安全的队列访问方式:当阻塞队列进行插入数据时,如果队列已满,线程将会阻塞等待直到队列非满;从阻塞队列取数据时,如果队列已空,线程将会阻塞等待直到队列非空。并发包下很多高级同步类的实现都是基于BlockingQueue实现的。BlockingQueue的特点如下:
1、BlockingQueue队列中不能包含nul元素;
2、BlockingQueue接口的实现类都必须是线程安全的,实现类一般通过“锁“保证线程安全;
3、BlockingQueue 可以是限定容量的,remainingCapacity0方法用于返回剩余可用容量,对于没有容量限制的BlockingQueue该方法总是返回Integer.MAX_VALUE。

简介: BlockingQueue 是个接口,你需要使用它的实现类之一来使用BlockingQueue,java.util.concurrent包下具有以下 BlockingQueue 接口的实现类:
1、ArrayBlockingQueue:ArrayBlockingQueue 是一个有界的阻塞队列,其内部实现是将对象放到一个数组里。有界也就意味着,它不能够存储无限多数量的元素。它有一个同一时间能够存储元素数量的上限。你可以在对其初始化的时候设定这个上限,但之后就无法对这个上限进行修改了(译者注:因为它是基于数组实现的,也就具有数组的特性:一旦初始化,大小就无法修改)。
2、DelayQueue:DelayQueue 对元素进行持有直到一个特定的延迟到期。注入其中的元素必须实现 java.util.concurrent.Delayed 接口。
3、LinkedBlockingQueue:LinkedBlockingQueue 内部以一个链式结构(链接节点)对其元素进行存储。如果需要的话,这一链式结构可以选择一个上限。如果没有定义上限,将使用 Integer.MAX_VALUE 作为上限。
4、PriorityBlockingQueue:PriorityBlockingQueue 是一个无界的并发队列。它使用了和类 java.util.PriorityQueue 一样的排序规则。你无法向这个队列中插入 null 值。所有插入到 PriorityBlockingQueue 的元素必须实现 java.lang.Comparable 接口。因此该队列中元素的排序就取决于你自己的 Comparable 实现。
5、SynchronousQueue:SynchronousQueue 是一个特殊的队列,它的内部同时只能够容纳单个元素。如果该队列已有一元素的话,试图向队列中插入一个新元素的线程将会阻塞,直到另一个线程将该元素从队列中抽走。同样,如果该队列为空,试图向队列中抽取一个元素的线程将会阻塞,直到另一个线程向队列中插入了一条新的元素。据此,把这个类称作一个队列显然是夸大其词了。它更多像是一个汇合点。

方法: 阻塞队列一共有四套方法分别用来进行插入、删除和读取,具体如下图所示:

抛出异常:如果试图的操作无法立即执行,抛一个异常。

返回特殊值:如果试图的操作无法立即执行,返回一个特定的值(常常是 true / false)。

阻塞线程:如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行。

超时:如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行,但等待时间不会超过给定值。返回一个特定值以告知该操作是否成功(典型的是true / false)。

Java高并发使用队列分批处理 java并发请求队列控制_java

可以看到,对于每种基本方法,“抛出异常”和“返回特殊值”的方法定义和Queue是完全一样的。BlockingQueue只是增加了两类和阻塞相关的方法:put(e)、take();offer(e,time,unit)、poll(time,unit)。

put(e)和take()方法会一直阻塞调用线程,直到线程被中断或队列状态可用,offer(e,time,unit)和poll(time,unit)方法会限时阻塞调用线程,直到超时或线程被中断或队列状态可用。

本文参考
作者: 记忆力不好