1. 程式人生 > >【ThreadPool】shutdown(),shutdownNow(),awaitTermination(n, TimeUnit) 這三個方法的應用

【ThreadPool】shutdown(),shutdownNow(),awaitTermination(n, TimeUnit) 這三個方法的應用

引子

之前線上一個定時任務出了問題,技術支援人員反映某用於傳送檔案的定時任務連續4個小時沒有工作過了,檢查了該任務的開關,資料庫的進度都沒找到問題。最後拿到日誌發現該定時任務在執行到某一步(阻塞性的操作)的時候再也找不到該執行緒的資訊了… 由此瞭解到該定時任務因為超時掛死從而不會執行下一次… 於是需要針對裡面某阻塞性的操作加個超時處理。。。

在加這個超時處理的時候,接觸到了執行緒池的管理。從而引入今天我們要聊的話題,這三個方法的作用以及正確的應用。

shutdown()

  • 不能接受新的submit
  • 並沒有任何的interrupt操作,會等待執行緒池中所有執行緒(執行中的以及排隊的)執行完畢

可以理解為是個標識性質的方法,標識這程式有意願在此刻終止執行緒池的後續操作。

shutdownNow()

  • 會嘗試interrupt執行緒池中正在執行的執行緒
  • 等待執行的執行緒也會被取消
  • 但是並不能保證一定能成功的interrupt執行緒池中的執行緒。
  • 會返回並未終止的執行緒列表List<Runnable>

shutdownNow()方法比shutdown()強硬了很多,不僅取消了排隊的執行緒而且確實嘗試終止當前正在執行的執行緒。

awaitTermination(n, TimeUnit)

  • 該方法返回值為boolean型別
  • 方法的兩個引數規定了方法的阻塞時間,在阻塞時間內
    除非所有執行緒都執行完畢才會提前返回true
  • 如果到了規定的時間,執行緒池中的執行緒並沒有全部結束返回false

利用這個阻塞方法的特性,我們可以優雅的關閉執行緒池中的任務。


// 建立執行緒池
// 執行業務邏輯
        pool.shutdown();
        if(!pool.awaitTermination(10, TimeUnit.SECONDS)) {
            pool.shutdownNow();
        }

進階:

  1. interrupt() 是否可以真正意義上的殺死執行緒?
  2. awaitTermination()到底是依據什麼來判斷執行緒結束的?