BlockingQueue
ArrayBlockingQueue 是一个有界的阻塞队列,其内部实现是将对象放到一个数组里。因为它是基于数组实现的,所以一旦初始化,大小就无法修改。
DelayQueue 对元素进行持有直到一个特定的延迟到期。注入其中的元素必须实现 java.util.concurrent.Delayed 接口。
LinkedBlockingQueue 内部以一个链式结构(链接节点)对其元素进行存储。如果需要的话,这一链式结构可以选择一个上限。如果没有定义上限,将使用 Integer.MAX_VALUE 作为上限。
PriorityBlockingQueue 是一个无界的并发队列。它使用了和类 java.util.PriorityQueue 一样的排序规则。你无法向这个队列中插入 null 值。所有插入到 PriorityBlockingQueue 的元素必须实现 java.lang.Comparable 接口。因此该队列中元素的排序就取决于你自己的 Comparable 实现。
SynchronousQueue 是一个特殊的队列,它的内部同时只能够容纳单个元素。如果该队列已有一元素的话,试图向队列中插入一个新元素的线程将会阻塞,直到另一个线程将该元素从队列中抽走。
BlockingQueue Demo
public class TestBlockingQueue {
public static void main(String[] args) {
final BlockingQueue<Integer> queue=new LinkedBlockingQueue<Integer>(3);
final Random random=new Random();
class Producer implements Runnable{
public void run() {
while(true){
try {
int i=random.nextInt(100);
queue.put(i); //当队列达到容量时候,会自动阻塞的
System.out.println("put "+ i + " into queue");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{
public void run() {
while(true){
try {
System.out.println("consumer:" + queue.take()); //当队列为空时,也会自动阻塞
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
new Thread(new Producer()).start();
new Thread(new Consumer()).start();
}
}
YY实现版本
接口
/*
AbstractQueue定义了对队列的基本操作;同时实现了BlockingQueue接口,
BlockingQueue表示阻塞型的队列,其对队列的操作可能会抛出异常;
同时也实现了Searializable接口,表示可以被序列化。
*/
public class ArrayBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
/** The queued items */
final Object[] items;
/** items index for next take, poll, peek or remove */
int takeIndex;
/** items index for next put, offer, or add */
int putIndex;
/** Number of elements in the queue */
int count;
/*
* Concurrency control uses the classic two-condition algorithm
* found in any textbook.
*/
/** Main lock guarding all access */
final ReentrantLock lock;
/** Condition for waiting takes */
private final Condition notEmpty;
/** Condition for waiting puts */
private final Condition notFull;
/**
* Shared state for currently active iterators, or null if there
* are known not to be any. Allows queue operations to update
* iterator state.
*/
transient Itrs itrs = null;
}
put方法
/**
* Inserts the specified element at the tail of this queue, waiting
* for space to become available if the queue is full.
*
* @throws InterruptedException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.lock;
/*
如果当前线程被打断则抛异常
如果当前线程未被中断,则获取锁
*/
lock.lockInterruptibly();
try {
while (count == items.length)
notFull.await();
enqueue(e);
} finally {
lock.unlock();
}
}
private static void checkNotNull(Object v) {
if (v == null)
throw new NullPointerException();
}
private void enqueue(E x) {
// assert lock.getHoldCount() == 1;
// assert items[putIndex] == null;
// 获取数组
final Object[] items = this.items;
// 将元素放入
items[putIndex] = x;
if (++putIndex == items.length) // 放入后存元素的索引等于数组长度(表示已满)
// 重置存索引为0
putIndex = 0;
// 元素数量加1
count++;
// 唤醒在notEmpty条件上等待的线程
notEmpty.signal();
}
take 方法
public E take() throws InterruptedException {
// 可重入锁
final ReentrantLock lock = this.lock;
// 如果当前线程未被中断,则获取锁,中断会抛出异常
lock.lockInterruptibly();
try {
while (count == 0) // 元素数量为0,即Object数组为空
// 则等待notEmpty条件
notEmpty.await();
// 出队列
return dequeue();
} finally {
// 释放锁
lock.unlock();
}
}
private E dequeue() {
// assert lock.getHoldCount() == 1;
// assert items[takeIndex] != null;
final Object[] items = this.items;
@SuppressWarnings("unchecked")
// 取元素
E x = (E) items[takeIndex];
// 该索引的值赋值为null
items[takeIndex] = null;
// 取值索引等于数组长度
if (++takeIndex == items.length)
// 重新赋值取值索引
takeIndex = 0;
// 元素个数减1
count--;
if (itrs != null)
itrs.elementDequeued();
// 唤醒在notFull条件上等待的线程
notFull.signal();
return x;
}