常见的实现是here,Java的内置实现是here。关于这两个实现,我有两个问题:
1)第一个实现在put()和take()方法上使用synchronized
关键字,这意味着只有一个线程可以访问一个方法。假设线程A调用put()并发现队列已满,所以它正在等待,那么没有人可以调用take()方法,因为锁尚未发布,如何使用实现?
2)Java的内置使用两个锁:takeLock和putLock,分别用于put()和take()。我看到间隔队列是一个链表,这不是线程安全的,怎么办呢?
答案 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
方法指示其他线程试图将元素放入完整队列。