Java阻塞队列实现问题

时间:2015-04-09 15:12:05

标签: java multithreading blockingqueue

常见的实现是here,Java的内置实现是here。关于这两个实现,我有两个问题:

1)第一个实现在put()和take()方法上使用synchronized关键字,这意味着只有一个线程可以访问一个方法。假设线程A调用put()并发现队列已满,所以它正在等待,那么没有人可以调用take()方法,因为锁尚未发布,如何使用实现?

2)Java的内置使用两个锁:takeLock和putLock,分别用于put()和take()。我看到间隔队列是一个链表,这不是线程安全的,怎么办呢?

1 个答案:

答案 0 :(得分:1)

正如一些评论中已经提到的,第一个实现只使用传统的wait()/ notify()机制,其中一个线程等待(当然还发布锁定)以便被其他线程通知。

第二个使用不同的锁,每个锁用于put和take操作。因此,各个操作(并发put()或take())是同步的。但是当队列满或空时,他们需要相互通信。因此,他们通过condition互相交流。检查两个私有方法 -

    /**
     * Signals a waiting take. Called only from put/offer (which do not
     * otherwise ordinarily lock takeLock.)
     */
    private void signalNotEmpty() {
        final ReentrantLock takeLock = this.takeLock;
        takeLock.lock();
        try {
            notEmpty.signal();
        } finally {
            takeLock.unlock();
        }
    }

    /**
     * Signals a waiting put. Called only from take/poll.
     */
    private void signalNotFull() {
        final ReentrantLock putLock = this.putLock;
        putLock.lock();
        try {
            notFull.signal();
        } finally {
            putLock.unlock();
        }
    }

put方法指示其他线程试图从空队列中获取/轮询,take方法指示其他线程试图将元素放入完整队列。