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 {
available.awaitNanos(delay);
} finally {
if (leader == thisThread)
leader = null;
}
}
}
}
} finally {
if (leader == null && q.peek() != null)
available.signal();
lock.unlock();
}
}
阻塞进程中分支条件比较复杂,我们一个一个看:
首先获取堆顶元素,假设为空,那么阐明队列中还没有元素,让以后线程在available上停止阻塞等候
假设堆顶元素不为空,那么查看它的过时时间,假设已到期,那么直接弹出堆顶元素
假设堆顶元素还没有到期,那么查看leader线程能否为空,假设leader线程不为空的话,表示曾经有其他线程在等候获取队列的元素,直接阻塞以后线程。
假设leader为空,那么把以后线程赋值给它,并调用awaitNanos办法,在阻塞delay时间后自动醒来。唤醒后,假设leader还是以后线程那么把它置为空,重新进入循环,再次判别堆顶元素能否到期。
当有队列中的元素完成出队后,假设leader线程为空,并且堆中还有元素,就唤醒阻塞在available上的其他线程,并释放持有的锁。
面试官:我留意到一个成绩,在下面的代码中,为什么要设置first = null呢?
(责任编辑:admin)