阻塞队列是这样一个队列,当尝试在队列为空时出队,或者尝试在队列已满时入队,它将阻塞。 尝试从空队列中出队的线程将被阻塞,直到其他线程插入一项到队列中为止。 尝试使一个项目进入满队列的线程将被阻塞,直到某个其他线程在队列中腾出空间为止,方法是使一个或多个项目出队或完全清除队列。
下面的示意图显示两个线程通过阻塞队列进行协作:
Java 5在java.util.concurrent包中附带了阻塞队列实现。 可以在我的java.util.concurrent.BlockingQueue教程中了解该类。 即使Java 5附带了阻塞队列实现,了解它们实现背后的理论也会很有用。
阻塞队列实现
阻塞队列的实现看起来类似于有界信号量。 下面是阻塞队列的简单实现:
public class BlockingQueue {
private List queue = new LinkedList();
private int limit = 10;
public BlockingQueue(int limit){
this.limit = limit;
}
public synchronized void enqueue(Object item)
throws InterruptedException {
while(this.queue.size() == this.limit) {
wait();
}
this.queue.add(item);
if(this.queue.size() == 1) {
notifyAll();
}
}
public synchronized Object dequeue()
throws InterruptedException{
while(this.queue.size() == 0){
wait();
}
if(this.queue.size() == this.limit){
notifyAll();
}
return this.queue.remove(0);
}
}
请注意,只有在队列大小等于大小界限(0或上限),则才会从enqueue()和dequeue()调用notifyAll()。 如果在调用enqueue()或dequeue()时队列大小不等于大小界限,则可能没有线程在等待入队或出队。