版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
//先转换为纳秒
long nanos = unit.toNanos(timeout);
//获得主锁
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (;;) {
//如果现在的state>=TERMINATED那可以直接return true了
if (runStateAtLeast(ctl.get(), TERMINATED))
return true;
if (nanos <= 0)
return false;
//mainLock的condition,执行等待
//如果时间没有被耗尽,那么会返回剩下的需要等待的时间,见aqs的awaitNanos方法
nanos = termination.awaitNanos(nanos);
}
} finally {
mainLock.unlock();
}
}
由于ThreadPoolExecutor只有在 tryTerminated()尝试终止线程池成功,将线程池更新为terminated状态后才会signalAll(),这时候awaitNanos方法返回,awaitTermination再次循环判断就会发现状态变成TERMINATED,直接返回true,如此达到了线程池一旦变成TERMINATED,awaitTermination能够立即返回的效果
/**
* Implements timed condition wait.
* <ol>
* <li> If current thread is interrupted, throw InterruptedException.
* <li> Save lock state returned by {@link #getState}.
* <li> Invoke {@link #release} with saved state as argument,
* throwing IllegalMonitorStateException if it fails.
* <li> Block until signalled, interrupted, or timed out.
* 持续阻塞,直到调用了signall或者interrupt或者超时
* <li> Reacquire by invoking specialized version of
* {@link #acquire} with saved state as argument.
* <li> If interrupted while blocked in step 4, throw InterruptedException.
* </ol>
*/
public final long awaitNanos(long nanosTimeout)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
long savedState = fullyRelease(node);
final long deadline = System.nanoTime() + nanosTimeout;
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
if (nanosTimeout <= 0L) {
transferAfterCancelledWait(node);
break;
}
if (nanosTimeout >= spinForTimeoutThreshold)
LockSupport.parkNanos(this, nanosTimeout);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
nanosTimeout = deadline - System.nanoTime();
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null)
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
return deadline - System.nanoTime();
}