一句話說明白Java線程池中shutdown和shutdownNow的區別

一般情況下,當我們頻繁的使用線程的時候,爲了節約資源快速響應需求,我們都會考慮使用線程池,線程池使用完畢都會想着關閉,關閉的時候一般情況下會用到shutdown和shutdownNow,這兩個函數都能夠用來關閉線程池,那麼他們倆之間的區別是什麼呢?下面我就用一句話來說明白shutdown和shutdownNow的區別。

一、一句話說明白shutdown和shutdownNow的區別

shutdown只是將線程池的狀態設置爲SHUTWDOWN狀態,正在執行的任務會繼續執行下去,沒有被執行的則中斷。而shutdownNow則是將線程池的狀態設置爲STOP,正在執行的任務則被停止,沒被執行任務的則返回。

        舉個工人吃包子的例子,一個廠的工人(Workers)正在吃包子(可以理解爲任務),假如接到shutdown的命令,那麼這個廠的工人們則會把手頭上的包子給吃完,沒有拿到手裏的籠子裏面的包子則不能吃!而如果接到shutdownNow的命令以後呢,這些工人們立刻停止吃包子,會把手頭上沒吃完的包子放下,更別提籠子裏的包子了。

二、線程狀態知識延伸

在ThreadPoolExecutor中定義了關於線程狀態的幾個變量如下:

   // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;

       1.當創建線程池後,初始時,線程池處於RUNNING狀態,此時線程池中的任務爲0;

  2.如果調用了shutdown()方法,則線程池處於SHUTDOWN狀態,此時線程池不能夠接受新的任務,它會等待所有任務執行完畢;

  3.如果調用了shutdownNow()方法,則線程池處於STOP狀態,此時線程池不能接受新的任務,並且會去嘗試終止正在執行的任務;

      4.當所有的任務已終止,ctl記錄的”任務數量”爲0,線程池會變爲TIDYING狀態。接着會執行terminated()函數。

  5.線程池處在TIDYING狀態時,執行完terminated()之後,就會由 TIDYING -> TERMINATED,線程池被設置爲TERMINATED狀態。

三、從shutdown和shutdownNow源碼分析兩者主要的區別

1.shutdown源碼

      public void shutdown() {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
            advanceRunState(SHUTDOWN);
            interruptIdleWorkers();
            onShutdown(); // hook for ScheduledThreadPoolExecutor
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
    }

2.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;
    }

     從源碼可以很清晰的看出兩者的區別,shutdown使用了以後會置狀態爲SHUTDOWN,而shutdownNow爲STOP。此外,shutdownNow會返回任務列表。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章