最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

前言

本章分為兩個(gè)議題

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

項(xiàng)目環(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í)行結(jié)果

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í)行完成之后,主線程會(huì)一直阻塞,那么如何關(guān)閉線程池呢?本章介紹 5 種在 ThreadPoolExecutor 中涉及關(guān)閉線程池的方法,如下所示

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

2.shutdown

第一種方法叫作 shutdown(),它可以安全地關(guān)閉一個(gè)線程池,調(diào)用 shutdown() 方法之后線程池并不是立刻就被關(guān)閉,因?yàn)檫@時(shí)線程池中可能還有很多任務(wù)正在被執(zhí)行,或是任務(wù)隊(duì)列中有大量正在等待被執(zhí)行的任務(wù),調(diào)用 shutdown() 方法后線程池會(huì)在執(zhí)行完正在執(zhí)行的任務(wù)和隊(duì)列中等待的任務(wù)后才徹底關(guān)閉。

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

這段源碼位置(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) {
            // 新建一個(gè)核心線程執(zhí)行任務(wù)
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        // 核心線程已滿,但是任務(wù)隊(duì)列未滿,添加到隊(duì)列中
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            // 任務(wù)成功添加到隊(duì)列以后,再次檢查是否需要添加新的線程,因?yàn)橐汛嬖诘木€程可能被銷毀了
            if (! isRunning(recheck) && remove(command))
                // 如果線程池處于非運(yùn)行狀態(tài),并且把當(dāng)前的任務(wù)從任務(wù)隊(duì)列中移除成功,則拒絕該任務(wù)
                reject(command);
            else if (workerCountOf(recheck) == 0)
                // 如果之前的線程已經(jīng)被銷毀完,新建一個(gè)非核心線程
                addWorker(null, false);
        }
        // 核心線程池已滿,隊(duì)列已滿,嘗試創(chuàng)建一個(gè)非核心新的線程
        else if (!addWorker(command, false))
            // 如果創(chuàng)建新線程失敗,說明線程池關(guān)閉或者線程池滿了,拒絕任務(wù)
            reject(command);
    }

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

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

3.isShutdown

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

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

4.isTerminated

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

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

直到所有任務(wù)都執(zhí)行完畢了,調(diào)用 isTerminated() 方法才會(huì)返回 true,這表示線程池已關(guān)閉并且線程池內(nèi)部是空的,所有剩余的任務(wù)都執(zhí)行完畢了。

5.awaitTermination

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

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

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

6.shutdownNow

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

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

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

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

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

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

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

相關(guān)文章

  • java初學(xué)者如何讓編程學(xué)習(xí)起來更簡單

    java初學(xué)者如何讓編程學(xué)習(xí)起來更簡單

    我們給大家?guī)硪黄P(guān)于java初學(xué)者如何讓編程學(xué)習(xí)起來更簡單的基礎(chǔ)性文章,有需要的朋友們可以學(xué)習(xí)下。
    2020-11-11
  • 詳解Spring Security的Web應(yīng)用和指紋登錄實(shí)踐

    詳解Spring Security的Web應(yīng)用和指紋登錄實(shí)踐

    這篇文章主要介紹了詳解Spring Security的Web應(yīng)用和指紋登錄實(shí)踐,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03
  • 詳細(xì)介紹Spring的配置文件

    詳細(xì)介紹Spring的配置文件

    這篇文章主要為大家詳細(xì)介紹了Spring中的配置文件的命名以及它的配置文件都有些什么。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟上小編一起學(xué)習(xí)一下
    2022-10-10
  • Springboot集成jsp及部署服務(wù)器實(shí)現(xiàn)原理

    Springboot集成jsp及部署服務(wù)器實(shí)現(xiàn)原理

    這篇文章主要介紹了Springboot集成jsp及部署服務(wù)器實(shí)現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 一文簡介Java中BlockingQueue阻塞隊(duì)列

    一文簡介Java中BlockingQueue阻塞隊(duì)列

    本文主要介紹了一文簡介Java中BlockingQueue阻塞隊(duì)列,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 一篇文章帶你深入理解JVM虛擬機(jī)讀書筆記--鎖優(yōu)化

    一篇文章帶你深入理解JVM虛擬機(jī)讀書筆記--鎖優(yōu)化

    這篇文章深入介紹了JVM虛擬機(jī)的鎖優(yōu)化,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2021-09-09
  • Java 對 Properties 文件的操作詳解及簡單實(shí)例

    Java 對 Properties 文件的操作詳解及簡單實(shí)例

    這篇文章主要介紹了Java 對 Properties 文件的操作詳解及簡單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • Spring @Conditional注解講解及示例詳解

    Spring @Conditional注解講解及示例詳解

    這篇文章主要介紹了Spring @Conditional注解講解及示例詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • 一文了解Java中枚舉的使用

    一文了解Java中枚舉的使用

    Java中枚舉,大家在項(xiàng)目中經(jīng)常使用吧,主要用來定義一些固定值。那你了解枚舉的本質(zhì)嗎?了解枚舉的一些常見用法嗎?本文就來為大家一一進(jìn)行詳解
    2022-09-09
  • Java 文件解壓縮實(shí)現(xiàn)代碼

    Java 文件解壓縮實(shí)現(xiàn)代碼

    這篇文章主要介紹了Java 文件解壓縮實(shí)現(xiàn)代碼,有需要的朋友可以參考一下
    2013-12-12

最新評論

磐安县| 福清市| 贺州市| 民乐县| 门头沟区| 重庆市| 堆龙德庆县| 黑河市| 道孚县| 永吉县| 鲜城| 新田县| 凤城市| 寿宁县| 麻栗坡县| 慈溪市| 彭州市| 宁安市| 丰都县| 舒城县| 织金县| 长宁县| 林甸县| 金沙县| 资源县| 沧源| 齐河县| 建德市| 邳州市| 五家渠市| 金湖县| 长宁县| 延寿县| 平陆县| 廉江市| 渝北区| 尼木县| 固安县| 阿拉善左旗| 陕西省| 新源县|