java中DelayQueue中take()方法的疑问?

新手上路,请多包涵

/**

 * 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就可以了呀!

所以我就矛盾了,到底是什么情况啊???

阅读 2.5k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题