/**
* Retrieves and removes the head of this queue, waiting if necessary
* until an element with an expired delay is available on this queue.
*
* @return the head of this queue
* @throws InterruptedException {@inheritDoc}
*/
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
// 获取可中断锁。
lock.lockInterruptibly();
try {
for (;;) {
// 从优先级队列中获取队列头元素
E first = q.peek();
if (first == null)
// 无元素,当前线程加入等待队列,并阻塞
available.await();
else {
// 通过getDelay 方法获取延迟时间
long delay = first.getDelay(NANOSECONDS);
if (delay <= 0)
// 延迟时间到期,获取并删除头部元素。
return q.poll();
first = null; // don't retain ref while waiting
if (leader != null)
available.await();
else {
Thread thisThread = Thread.currentThread();
leader = thisThread;
try {
// 线程节点进入等待队列 x 纳秒。
available.awaitNanos(delay);
} finally {
// ??????????
if (leader == thisThread)
leader = null;
}
}
}
}
} finally {
// leader == null且还存在元素的话,唤醒一个消费线程。
if (leader == null && q.peek() != null)
available.signal();
lock.unlock();
}
}
注释为问号的地方判断leader == thisThread的逻辑是怎么样的呢?
我的理解是当前线程在available的阻塞队列上等待delay纳秒的过程中,只可能是由线程向队列q中插入了新的元素,并且经过排序后该元素变成了队首元素时才会将leader置为null,任何执行take操作的其他线程是不可能修改leader的值的,所以leader要么为null,要么为thisThread。在这种理解的基础上,问号处的if语句的判断就没有意义了,直接将leader置为null就可以了呀!
所以我就矛盾了,到底是什么情况啊???