Java阻塞队列实现问题
Java Blocking Queue Implementation Questions
常见的实现是here, Java's built-in implementation is here。关于这两个实现,我有两个问题:
1) 第一个实现在 put() 和 take() 方法上使用 synchronized
关键字,这意味着只有一个线程可以访问一个方法。比方说如果线程A调用put()发现队列已满,在等待,那么take()方法谁也调用不了,因为锁还没有释放,如何实现呢?
2) Java的内置使用了两个锁:takeLock和putLock,分别用在put()和take()中。我看到区间队列是一个链表,不是线程安全的,怎么办?
正如一些评论中已经提到的,第一个实现仅使用传统的 wait()/notify() 机制,其中一个线程等待(当然还有释放锁)以接收其他线程的通知。
第二个为放置和获取操作使用不同的锁。所以各个操作(同时进行的 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/poll 并且 take
方法向其他线程发出信号,试图将元素放入完整队列。
常见的实现是here, Java's built-in implementation is here。关于这两个实现,我有两个问题:
1) 第一个实现在 put() 和 take() 方法上使用 synchronized
关键字,这意味着只有一个线程可以访问一个方法。比方说如果线程A调用put()发现队列已满,在等待,那么take()方法谁也调用不了,因为锁还没有释放,如何实现呢?
2) Java的内置使用了两个锁:takeLock和putLock,分别用在put()和take()中。我看到区间队列是一个链表,不是线程安全的,怎么办?
正如一些评论中已经提到的,第一个实现仅使用传统的 wait()/notify() 机制,其中一个线程等待(当然还有释放锁)以接收其他线程的通知。
第二个为放置和获取操作使用不同的锁。所以各个操作(同时进行的 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/poll 并且 take
方法向其他线程发出信号,试图将元素放入完整队列。