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();
}