Basic Of Concurrency(十八: 阻塞队列)

604 阅读1分钟

一个队列在队空和队满的情况下进行出队和进队操作会发生阻塞,这种队列我们称之为阻塞队列.队列在队空的情况下进行出队操作会发生阻塞,直到有一到多个队项入队为止.队列在队满的情况下入队会发生阻塞,直到有队项出列或队空的情况下.

这是一个两个线程通过阻塞队列协作的示例图:

我们可以看出一个线程从队列中取出队项,一个线程往队列中放入对项.

Java5的java.util.concurrent包中已有现成的阻塞队列实现.但我们仍然很有必要知道它的底层实现原理.

阻塞队列实现

一个阻塞队列的实现看起来有点像BoundedSemaphore.如下一个简单的阻塞队列实现:

public class BlockingQueue<T> {
    private List<T> 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所著Java Concurrency and Multithreading Tutorial

上一篇: Semaphores
下一篇: 线程池