一个队列在队空和队满的情况下进行出队和进队操作会发生阻塞,这种队列我们称之为阻塞队列.队列在队空的情况下进行出队操作会发生阻塞,直到有一到多个队项入队为止.队列在队满的情况下入队会发生阻塞,直到有队项出列或队空的情况下.
这是一个两个线程通过阻塞队列协作的示例图:
我们可以看出一个线程从队列中取出队项,一个线程往队列中放入对项.
Java5的java.util.concurrent
包中已有现成的阻塞队列实现.但我们仍然很有必要知道它的底层实现原理.
阻塞队列实现
一个阻塞队列的实现看起来有点像BoundedSemaphore.如下一个简单的阻塞队列实现:
public class BlockingQueue{ private List queue = new ArrayList<>(); private int limit = 10; public BlockingQueue(int limit) { this.limit = limit; } public synchronized void enqueue(T item) { while (queue.size() == limit) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if (queue.size() == 0) { notifyAll(); } queue.add(item); } public synchronized T dequeue(){ while (queue.size() == 0){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if(queue.size() == limit){ notifyAll(); } return queue.remove(0); }}复制代码
我们可以注意到当调用enqueue()和dequeue()发现队满和队空时需要调用notifyAll()来唤醒相应的线程来取出和放入队项.如果队列大小没有达到限制,那么两个线程可以在不用阻塞线程的情况下放入和取出队项.
该系列博文为笔者复习基础所著译文或理解后的产物,复习原文来自Jakob Jenkov所著