線程池關閉及等待關閉方法


1.shutdown方法

//不會接收新任務,但會繼續處理隊列中的任務
public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            //校驗權限(如果沒有聲明或者配置SecurityManager,是會通過的)
            checkShutdownAccess();
            //線程池狀態設置為SHUTDOWN狀態,
            advanceRunState(SHUTDOWN);
            //interrupt 空閑工作線程
            interruptIdleWorkers();
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
    }

interruptIdleWorkers方法

private void interruptIdleWorkers(boolean onlyOne) {
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        for (Worker w : workers) {
            Thread t = w.thread;
            //w.tryLock(),嘗試獲取鎖(如果能獲取到,說明沒有在執行任務,可中斷)
            //在runWorker  w.lock和w.unlock之間的不會中斷
            if (!t.isInterrupted() && w.tryLock()) {
                try {
                    t.interrupt();
                } catch (SecurityException ignore) {
                } finally {
                    w.unlock();
                }
            }
            if (onlyOne)
                break;
        }
    } finally {
        mainLock.unlock();
    }
}

2.shutdownNow方法

//不接受新任務,不處理隊列中的任務,並中斷正在進行的任務(中斷線程,但當前任務會繼續執行完在結束)
public List<Runnable> shutdownNow() {
    List<Runnable> tasks;
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        //檢查是否有權限關閉線程池,和中斷工作線程
        checkShutdownAccess();
        //線程池狀態設置為STOP狀態,
        advanceRunState(STOP);
        //interrupt所有已經啟動(start())的工作線程(runWorker->w.unlock()之后)
        interruptWorkers();
        //清空隊列中的任務,並返回未處理的任務
        tasks = drainQueue();
    } finally {
        mainLock.unlock();
    }
    //嘗試終止線程池
    tryTerminate();
    return tasks;
}

interruptIfStarted

shutdownNow-> interruptWorkers-> interruptIfStarted,

//中斷已經執行runworker的工作線程
void interruptIfStarted() {
    Thread t;
    //w.unlock:state=0;w.lock:state=1,在執行到runWorker,w.unlock時就可以中斷了
    if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
        try {
            t.interrupt();
        } catch (SecurityException ignore) {
        }
    }
}

3.awaitTermination

這個不是關閉方法,是可阻塞等待線程池關閉的方法

//1:在超時(timeout)后仍未結束,返回false
//2: 在線程池終止時,會返回true
public boolean awaitTermination(long timeout, TimeUnit unit)
    throws InterruptedException {
    //以納秒為單位,阻塞的最大時間,超過這個時間,如果線程池還沒終止,返回false
    long nanos = unit.toNanos(timeout);
    final ReentrantLock mainLock = this.mainLock;
    mainLock.lock();
    try {
        for (;;) {
            //如果線程池已經終止了。返回true
            if (runStateAtLeast(ctl.get(), TERMINATED))
                return true;
            //如果超時了,返回false
            if (nanos <= 0)
                return false;
            //阻塞方法,直到時間超過nanos或者通過tryTerminate()->termination.signalAll();喚醒
            nanos = termination.awaitNanos(nanos);
        }
    } finally {
        mainLock.unlock();
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM