亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談Java關閉線程池shutdown和shutdownNow的區(qū)別

 更新時間:2021年09月26日 11:01:48   作者:不懂的浪漫  
本文主要介紹了Java關閉線程池shutdown和shutdownNow的區(qū)別,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

前言

本章分為兩個議題

  • 如何正確關閉線程池
  • shutdown 和 shutdownNow 的區(qū)別

項目環(huán)境

1.線程池示例

public class ShutDownThreadPoolDemo {

    private ExecutorService service = Executors.newFixedThreadPool(10);

    public static void main(String[] args) {
        new ShutDownThreadPoolDemo().executeTask();
    }

    public void executeTask() {
        for (int i = 0; i < 100; i++) {
            service.submit(() -> {
                System.out.println(Thread.currentThread().getName() + "->執(zhí)行");
            });
        }
    }
}

執(zhí)行結果

pool-1-thread-2->執(zhí)行
pool-1-thread-3->執(zhí)行
pool-1-thread-1->執(zhí)行
pool-1-thread-4->執(zhí)行
pool-1-thread-5->執(zhí)行
pool-1-thread-6->執(zhí)行
...

執(zhí)行完成之后,主線程會一直阻塞,那么如何關閉線程池呢?本章介紹 5 種在 ThreadPoolExecutor 中涉及關閉線程池的方法,如下所示

  • void shutdown
  • boolean isShutdown
  • boolean isTerminated
  • boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException
  • List<Runnable> shutdownNow

2.shutdown

第一種方法叫作 shutdown(),它可以安全地關閉一個線程池,調用 shutdown() 方法之后線程池并不是立刻就被關閉,因為這時線程池中可能還有很多任務正在被執(zhí)行,或是任務隊列中有大量正在等待被執(zhí)行的任務,調用 shutdown() 方法后線程池會在執(zhí)行完正在執(zhí)行的任務和隊列中等待的任務后才徹底關閉。

調用 shutdown() 方法后如果還有新的任務被提交,線程池則會根據(jù)拒絕策略直接拒絕后續(xù)新提交的任務。

這段源碼位置(jdk 1.8 版本)

java.util.concurrent.ThreadPoolExecutor#execute

    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        // 線程池中的線程比核心線程數(shù)少 
        if (workerCountOf(c) < corePoolSize) {
            // 新建一個核心線程執(zhí)行任務
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        // 核心線程已滿,但是任務隊列未滿,添加到隊列中
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            // 任務成功添加到隊列以后,再次檢查是否需要添加新的線程,因為已存在的線程可能被銷毀了
            if (! isRunning(recheck) && remove(command))
                // 如果線程池處于非運行狀態(tài),并且把當前的任務從任務隊列中移除成功,則拒絕該任務
                reject(command);
            else if (workerCountOf(recheck) == 0)
                // 如果之前的線程已經(jīng)被銷毀完,新建一個非核心線程
                addWorker(null, false);
        }
        // 核心線程池已滿,隊列已滿,嘗試創(chuàng)建一個非核心新的線程
        else if (!addWorker(command, false))
            // 如果創(chuàng)建新線程失敗,說明線程池關閉或者線程池滿了,拒絕任務
            reject(command);
    }

1373 行 if (! isRunning(recheck) && remove(command))
如果線程池被關閉,將當前的任務從任務隊列中移除成功,并拒絕該任務

1378 行 else if (!addWorker(command, false))
如果創(chuàng)建新線程失敗,說明線程池關閉或者線程池滿了,拒絕任務。

3.isShutdown

第二個方法叫作 isShutdown(),它可以返回 true 或者 false 來判斷線程池是否已經(jīng)開始了關閉工作,也就是是否執(zhí)行了 shutdown 或者 shutdownNow 方法。

這里需要注意,如果調用 isShutdown() 方法的返回的結果為 true 并不代表線程池此時已經(jīng)徹底關閉了,這僅僅代表線程池開始了關閉的流程,也就是說,此時可能線程池中依然有線程在執(zhí)行任務,隊列里也可能有等待被執(zhí)行的任務。

4.isTerminated

第三種方法叫作 isTerminated(),這個方法可以檢測線程池是否真正“終結”了,這不僅代表線程池已關閉,同時代表線程池中的所有任務都已經(jīng)都執(zhí)行完畢了。

比如我們上面提到的情況,如果此時已經(jīng)調用了 shutdown 方法,但是還有任務沒有執(zhí)行完,那么此時調用 isShutdown 方法返回的是 true,而 isTerminated 方法則會返回 false。

直到所有任務都執(zhí)行完畢了,調用 isTerminated() 方法才會返回 true,這表示線程池已關閉并且線程池內部是空的,所有剩余的任務都執(zhí)行完畢了。

5.awaitTermination

第四個方法叫作 awaitTermination(),它本身并不是用來關閉線程池的,而是主要用來判斷線程池狀態(tài)的。

比如我們給 awaitTermination 方法傳入的參數(shù)是 10 秒,那么它就會陷入 10 秒鐘的等待,直到發(fā)生以下三種情況之一:

  • 等待期間(包括進入等待狀態(tài)之前)線程池已關閉并且所有已提交的任務(包括正在執(zhí)行的和隊列中等待的)都執(zhí)行完畢,相當于線程池已經(jīng)“終結”了,方法便會返回 true
  • 等待超時時間到后,第一種線程池“終結”的情況始終未發(fā)生,方法返回 false
  • 等待期間線程被中斷,方法會拋出 InterruptedException 異常
  • 調用 awaitTermination 方法后當前線程會嘗試等待一段指定的時間,如果在等待時間內,線程池已關閉并且內部的任務都執(zhí)行完畢了,也就是說線程池真正“終結”了,那么方法就返回 true,否則超時返回 fasle。

6.shutdownNow

最后一個方法是 shutdownNow(),它和 shutdown() 的區(qū)別就是多了一個 Now,表示立刻關閉的意思,不推薦使用這一種方式關閉線程池。

在執(zhí)行 shutdownNow 方法之后,首先會給所有線程池中的線程發(fā)送 interrupt 中斷信號,嘗試中斷這些任務的執(zhí)行,然后會將任務隊列中正在等待的所有任務轉移到一個 List 中并返回,我們可以根據(jù)返回的任務 List 來進行一些補救的操作,例如記錄在案并在后期重試。

shutdownNow 源碼如下:

    public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(STOP);
            interruptWorkers();
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
        return tasks;
    }

interruptWorkers

  • 讓每一個已經(jīng)啟動的線程都中斷,這樣線程就可以在執(zhí)行任務期間檢測到中斷信號并進行相應的處理,提前結束任務

7.shutdown 和 shutdownNow 的區(qū)別?

  • shutdown 會等待線程池中的任務執(zhí)行完成之后關閉線程池,而 shutdownNow 會給所有線程發(fā)送中斷信號,中斷任務執(zhí)行,然后關閉線程池
  • shutdown 沒有返回值,而 shutdownNow 會返回關閉前任務隊列中未執(zhí)行的任務集合(List)

到此這篇關于淺談Java關閉線程池shutdown和shutdownNow的區(qū)別的文章就介紹到這了,更多相關Java關閉線程池shutdown和shutdownNow內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java中讀寫鎖ReadWriteLock的原理與應用詳解

    Java中讀寫鎖ReadWriteLock的原理與應用詳解

    Java并發(fā)編程提供了讀寫鎖,主要用于讀多寫少的場景,今天我們就重點來講解讀寫鎖ReadWriteLock的原理與應用場景,感興趣的可以了解一下
    2022-09-09
  • Java enum 對枚舉元素的賦值和取值方式

    Java enum 對枚舉元素的賦值和取值方式

    這篇文章主要介紹了Java enum 對枚舉元素的賦值和取值方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 深入學習java位運算的基礎知識

    深入學習java位運算的基礎知識

    位運算是直接對整數(shù)在內存中的二進制位進行操作嗎,位運算即可以節(jié)約內存,同時使程序速度更快效率更高。文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,下面我們來一起學習下吧
    2019-06-06
  • 圖解Spring框架的設計理念與設計模式

    圖解Spring框架的設計理念與設計模式

    這篇文章主要通過多圖詳細解釋Spring框架的設計理念與設計模式,需要的朋友可以參考下
    2015-08-08
  • Java加密 消息摘要算法SHA實現(xiàn)詳解

    Java加密 消息摘要算法SHA實現(xiàn)詳解

    這篇文章主要介紹了Java加密 消息摘要算法SHA實現(xiàn)詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-07-07
  • IDEA快捷鍵和各種實用功能小結

    IDEA快捷鍵和各種實用功能小結

    這篇文章主要介紹了IDEA快捷鍵總結和各種實用功能,包括IDEA中內容輔助鍵和快捷鍵,修改自動補全快捷鍵,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • JWT 設置token過期時間無效的解決

    JWT 設置token過期時間無效的解決

    這篇文章主要介紹了JWT 設置token過期時間無效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 解析ConcurrentHashMap: 預熱(內部一些小方法分析)

    解析ConcurrentHashMap: 預熱(內部一些小方法分析)

    ConcurrentHashMap是由Segment數(shù)組結構和HashEntry數(shù)組結構組成。Segment的結構和HashMap類似,是一種數(shù)組和鏈表結構,今天給大家普及java面試常見問題---ConcurrentHashMap知識,一起看看吧
    2021-06-06
  • Fluent MyBatis實現(xiàn)動態(tài)SQL

    Fluent MyBatis實現(xiàn)動態(tài)SQL

    MyBatis 令人喜歡的一大特性就是動態(tài) SQL。本文主要介紹了Fluent MyBatis實現(xiàn)動態(tài)SQL,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • java刪除指定目錄下所有空文件夾的方法

    java刪除指定目錄下所有空文件夾的方法

    這篇文章主要介紹了java刪除指定目錄下所有空文件夾的方法,涉及java針對文件與目錄的遍歷及目錄刪除相關操作技巧,需要的朋友可以參考下
    2016-08-08

最新評論