溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java如何使用ExecutorService關閉線程池?

發布時間:2020-05-23 16:50:46 來源:億速云 閱讀:1344 作者:鴿子 欄目:編程語言

ExecutorService讓我們可以優雅地在程序中使用線程池來創建和管理線程,而且性能佳、開銷小,還可以有效地控制最大并發線程數,是我們在java并發編程中會經常使用到的。

每一個線程都會占用系統資源,因此線程池的關閉與清理同樣重要,本文介紹我們如何優雅地關閉線程池。

一. ExecutorService中關閉線程池的方法

1. shutdown()

停止接收新任務,原來的任務繼續執行

  1. 停止接收新的submit的任務;
  2. 已經提交的任務(包括正在跑的和隊列中等待的),會繼續執行完成;
  3. 等到第2步完成后,才真正停止;

2. shutdownNow()

停止接收新任務,原來的任務停止執行

  1. 跟 shutdown() 一樣,先停止接收新submit的任務;
  2. 忽略隊列里等待的任務;
  3. 嘗試將正在執行的任務interrupt中斷;
  4. 返回未執行的任務列表;

    說明:它試圖終止線程的方法是通過調用 Thread.interrupt() 方法來實現的,這種方法的作用有限,如果線程中沒有sleep 、wait、Condition、定時鎖等應用, interrupt() 方法是無法中斷當前的線程的。所以,shutdownNow() 并不代表線程池就一定立即就能退出,它也可能必須要等待所有正在執行的任務都執行完成了才能退出。但是大多數時候是能立即退出的。

3. awaitTermination(long timeOut, TimeUnit unit)

當前線程阻塞,timeout 和 TimeUnit 兩個參數,用于設定超時的時間及單位,當前線程阻塞,直到:

  • 等所有已提交的任務(包括正在跑的和隊列中等待的)執行完;
  • 或者 等超時時間到了(timeout 和 TimeUnit設定的時間);
  • 或者 線程被中斷,拋出InterruptedException

然后會監測 ExecutorService 是否已經關閉,返回true(shutdown請求后所有任務執行完畢)或false(已超時)

二. 三種方法的區別

1. shutdown() 和 shutdownNow() 的區別

  • shutdown() 只是關閉了提交通道,用submit()是無效的;而內部該怎么跑還是怎么跑,跑完再停。
  • shutdownNow() 能立即停止線程池,正在跑的和正在等待的任務都停下了。

2. shutdown() 和 awaitTermination() 的區別

  • shutdown() 后,不能再提交新的任務進去;但是 awaitTermination() 后,可以繼續提交。
  • awaitTermination() 是阻塞的,返回結果是線程池是否已停止(true/false);shutdown() 不阻塞。

3. 總結

  1. 優雅的關閉,用 shutdown()
  2. 想立馬關閉,并得到未執行任務列表,用shutdownNow()
  3. 優雅的關閉,并允許關閉聲明后新任務能提交,用 awaitTermination()
  4. 關閉功能 【從強到弱】 依次是:shuntdownNow() > shutdown() > awaitTermination()

三. RunTime.getRunTime().addShutdownHook()的作用

RunTime.getRunTime().addShutdownHook()的作用就是在JVM銷毀前執行的最后一個線程,通過addShutdownHook添加鉤子,當系統執行完這些鉤子后,jvm才會關閉,因此我們可以在這個線程中把我們前面使用ExecutorService創建的線程池優雅地關閉掉。
在web3j中異步執行類(Async)中有如下代碼:

// 創建線程池
private static final ExecutorService executor = Executors.newCachedThreadPool();

// 添加關閉線程池的鉤子
static {
    Runtime.getRuntime().addShutdownHook(new Thread(() - > shutdown(executor)));
}

// 關閉線程池的鉤子函數
private static void shutdown(ExecutorService executorService) {
    // 第一步:使新任務無法提交
    executorService.shutdown();
    try {
        // 第二步:等待未完成任務結束
        if(!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
             // 第三步:取消當前執行的任務
            executorService.shutdownNow();
            // 第四步:等待任務取消的響應
            if(!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                System.err.println("Thread pool did not terminate");
            }
        }
    } catch(InterruptedException ie) {
        // 第五步:出現異常后,重新取消當前執行的任務
        executorService.shutdownNow();
        Thread.currentThread().interrupt(); // 設置本線程中斷狀態
    }
}

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女