java如何使用ExecutorService關(guān)閉線程池?-創(chuàng)新互聯(lián)

ExecutorService讓我們可以優(yōu)雅地在程序中使用線程池來創(chuàng)建和管理線程,而且性能佳、開銷小,還可以有效地控制大并發(fā)線程數(shù),是我們在java并發(fā)編程中會經(jīng)常使用到的。

創(chuàng)新互聯(lián)自2013年創(chuàng)立以來,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都網(wǎng)站設(shè)計、成都網(wǎng)站制作網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元萬州做網(wǎng)站,已為上家服務(wù),為萬州各地企業(yè)和個人服務(wù),聯(lián)系電話:18980820575

每一個線程都會占用系統(tǒng)資源,因此線程池的關(guān)閉與清理同樣重要,本文介紹我們?nèi)绾蝺?yōu)雅地關(guān)閉線程池。

一. ExecutorService中關(guān)閉線程池的方法

1. shutdown()

停止接收新任務(wù),原來的任務(wù)繼續(xù)執(zhí)行

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

2. shutdownNow()

停止接收新任務(wù),原來的任務(wù)停止執(zhí)行

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

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

3. awaitTermination(long timeOut, TimeUnit unit)

當(dāng)前線程阻塞,timeout 和 TimeUnit 兩個參數(shù),用于設(shè)定超時的時間及單位,當(dāng)前線程阻塞,直到:

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

然后會監(jiān)測 ExecutorService 是否已經(jīng)關(guān)閉,返回true(shutdown請求后所有任務(wù)執(zhí)行完畢)或false(已超時)

二. 三種方法的區(qū)別

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

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

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

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

3. 總結(jié)

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

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

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

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

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

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

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

文章名稱:java如何使用ExecutorService關(guān)閉線程池?-創(chuàng)新互聯(lián)
文章URL:http://bm7419.com/article24/cdeeje.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、動態(tài)網(wǎng)站、云服務(wù)器、品牌網(wǎng)站設(shè)計網(wǎng)站導(dǎo)航、移動網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司