BlockingQueue
一个线程往阻塞队列里放资源.另一个线程进行消费.如果队列满的话,放入的线程会被阻塞.相反.如果队列为空,消费的线程就会被阻塞.
BlockingQueue 的方法
BlockingQueue 具有 4 组不同的方法用于插入、移除以及对队列中的元素进行检查。如果请求的操作不能得到立即执行的话,每个方法的表现也不同。
抛异常: 如果试图的操作无法立即执行,抛一个异常。源码如下.(只是以某一个队列为例子,理解意思就好,后面会整理一下各个队列的源码)
特定值: 如果试图的操作无法立即执行,返回一个特定的值(常常是 true / false)。
阻塞: 如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行。
超时: 如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行,但等待时间不会超过给定值。返回一个特定值以告知该操作是否成功(典型的是 true / false)。
无法向一个 BlockingQueue 中插入 null。源码如下.
BlockingDeque
java.util.concurrent 包里的 BlockingDeque 接口表示一个线程安放入和提取实例的双端队列。
BlockingDeque 类是一个双端队列,在不能够插入元素时,它将阻塞住试图插入元素的线程;在不能够抽取元素时,它将阻塞住试图抽取的线程。
为什么是双端队列呢.从源码就可以看出来,它可以在头尾添加节点.
/**
* Inserts the specified element at the front of this deque if it is
* possible to do so immediately without violating capacity restrictions,
* throwing an {@code IllegalStateException} if no space is currently
* available. When using a capacity-restricted deque, it is generally
* preferable to use {@link #offerFirst(Object) offerFirst}.
*
* @param e the element to add
* @throws IllegalStateException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified element is null
* @throws IllegalArgumentException {@inheritDoc}
*/
void addFirst(E e);
/**
* Inserts the specified element at the end of this deque if it is
* possible to do so immediately without violating capacity restrictions,
* throwing an {@code IllegalStateException} if no space is currently
* available. When using a capacity-restricted deque, it is generally
* preferable to use {@link #offerLast(Object) offerLast}.
*
* @param e the element to add
* @throws IllegalStateException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified element is null
* @throws IllegalArgumentException {@inheritDoc}
*/
void addLast(E e);
/**
* Inserts the specified element at the front of this deque if it is
* possible to do so immediately without violating capacity restrictions,
* returning {@code true} upon success and {@code false} if no space is
* currently available.
* When using a capacity-restricted deque, this method is generally
* preferable to the {@link #addFirst(Object) addFirst} method, which can
* fail to insert an element only by throwing an exception.
*
* @param e the element to add
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified element is null
* @throws IllegalArgumentException {@inheritDoc}
*/
boolean offerFirst(E e);
/**
* Inserts the specified element at the end of this deque if it is
* possible to do so immediately without violating capacity restrictions,
* returning {@code true} upon success and {@code false} if no space is
* currently available.
* When using a capacity-restricted deque, this method is generally
* preferable to the {@link #addLast(Object) addLast} method, which can
* fail to insert an element only by throwing an exception.
*
* @param e the element to add
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException if the specified element is null
* @throws IllegalArgumentException {@inheritDoc}
*/
boolean offerLast(E e);
BlockingDeque 的方法
抛异常: 如果试图的操作无法立即执行,抛一个异常。
特定值: 如果试图的操作无法立即执行,返回一个特定的值(常常是 true / false)。
阻塞: 如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行。
超时:如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行,但等待时间不会超过给定值。返回一个特定值以告知该操作是否成功(典型的是 true / false)。
数组阻塞队列 ArrayBlockingQueue
ArrayBlockingQueue 类实现了 BlockingQueue 接口。
ArrayBlockingQueue 是一个有界的阻塞队列,其内部实现是将对象放到一个数组里。然后它是一个有界队列.它不能够存储无限多数量的元素。因为是数组,所以初始化了就不能在修改.源码如下.
/**
* Creates an {@code ArrayBlockingQueue} with the given (fixed)
* capacity and the specified access policy.
*
* @param capacity the capacity of this queue
* @param fair if {@code true} then queue accesses for threads blocked
* on insertion or removal, are processed in FIFO order;
* if {@code false} the access order is unspecified.
* @throws IllegalArgumentException if {@code capacity < 1}
*/
public ArrayBlockingQueue(int capacity, boolean fair) {
if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull = lock.newCondition();
}
延迟队列 DelayQueue
DelayQueue 实现了 BlockingQueue 接口。
DelayQueue 对元素进行持有直到一个特定的延迟到期。注入其中的元素必须实现 java.util.concurrent.Delayed 接口,该接口定义:
public interface Delayed extends Comparable<Delayed> {
/**
* Returns the remaining delay associated with this object, in the
* given time unit.
*
* @param unit the time unit
* @return the remaining delay; zero or negative values indicate
* that the delay has already elapsed
*/
long getDelay(TimeUnit unit);
}
DelayQueue 将会在每个元素的 getDelay() 方法返回的值的时间段之后才释放掉该元素。如果返回的是 0 或者负值,延迟将被认为过期,该元素将会在 DelayQueue 的下一次 take 被调用的时候被释放掉。
链阻塞队列 LinkedBlockingQueue
LinkedBlockingQueue 类实现了 BlockingQueue 接口。
LinkedBlockingQueue 内部以一个链式结构(链接节点)对其元素进行存储。如果初始化没有设置容量的话,会默认使用 Integer.MAX_VALUE 作为上限.
优先级的阻塞队列 PriorityBlockingQueue
PriorityBlockingQueue 类实现了 BlockingQueue 接口。
PriorityBlockingQueue 是一个无界的并发队列。它使用了和类 java.util.PriorityQueue 一样的排序规则。你无法向这个队列中插入 null 值。 所有插入到 PriorityBlockingQueue 的元素必须实现 java.lang.Comparable 接口。因此该队列中元素的排序就取决于你自己的 Comparable 实现。 注意 PriorityBlockingQueue 对于具有相等优先级(compare() == 0)的元素并不强制任何特定行为。
同步队列 SynchronousQueue
SynchronousQueue 类实现了 BlockingQueue 接口。
SynchronousQueue 是一个特殊的队列,它的内部同时只能够容纳单个元素。如果该队列已有一元素的话,试图向队列中插入一个新元素的线程将会阻塞,直到另一个线程将该元素从队列中抽走。同样,如果该队列为空,试图向队列中抽取一个元素的线程将会阻塞,直到另一个线程向队列中插入了一条新的元素。
链阻塞双端队列 LinkedBlockingDeque
LinkedBlockingDeque 类实现了 BlockingDeque 接口。
LinkedBlockingDeque 是一个双端队列,在它为空的时候,一个试图从中抽取数据的线程将会阻塞,无论该线程是试图从哪一端抽取数据。