在多線程編程中,經常會遇到將線程池關閉的case。這就會使用到ShutDown和ShutDownNow,這兩者到底適合哪種使用場景呢?
個人對其進行了一番測試:
場景一:所有線程都是一個task,都是批處理作業,相互之間沒有什么關系,某個線程的異常對結果影響不大。那么所有線程都能在執行任務結束之后可以正常結束,程序能在所有task都做完之后正常退出,適合用ShutDown。
場景二:所有線程都是一個工人,源源不斷的從任務池中接收任務,整個任務周期非常長。但是,如果一個線程在做某個任務的時候失敗,則整個結果就是失敗的,其他worker再繼續做剩下的任務也是徒勞,這就需要讓他們全部停止當前的工作。這里使用ShutDownNow就可以讓該pool中的所有線程都停止當前的工作,從而迫使所有線程執行退出。從而讓主程序正常退出。
import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class TestShutDown { public static void main(String[] args) { try { testShutDown(100); testShutDowNow(200); } catch (InterruptedException e) { e.printStackTrace(); } } public static void testShutDown(int startNo) throws InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(2); for (int i = 0; i < 5; i++) { executorService.execute(getTask(i + startNo)); } executorService.shutdown(); executorService.awaitTermination(1, TimeUnit.DAYS); System.out.println("shutDown->all thread shutdown"); } public static void testShutDowNow(int startNo) throws InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(2); for (int i = 0; i < 5; i++) { executorService.execute(getTask(i + startNo)); } executorService.shutdownNow(); executorService.awaitTermination(1, TimeUnit.DAYS); System.out.println("shutdownNow->all thread shutdown"); } public static Runnable getTask(int threadNo) { final Random rand = new Random(); final int no = threadNo; Runnable task = new Runnable() { @Override public void run() { try { System.out.println(no + "-->" + rand.nextInt(10)); Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("thread " + no + " has error" + e); } } }; return task; } }
執行結果:
shutDown后可以使用awaitTermination等待所有線程執行完畢當前任務。
shutDownNow就會迫使當前執行的所有任務停止工作。
100-->2 101-->9 102-->0 103-->0 104-->9 shutDown->all thread shutdown 200-->9 201-->8 thread 200 has errorjava.lang.InterruptedException: sleep interrupted thread 201 has errorjava.lang.InterruptedException: sleep interrupted shutdownNow->all thread shutdown