關閉時可以使用以下代碼java
public static void waitUntilTerminate(final ExecutorService executorService, final int timeout) { try { executorService.shutdown(); if (!executorService.awaitTermination(timeout, TimeUnit.SECONDS)) { //超時後直接關閉 executorService.shutdownNow(); } } catch (InterruptedException e) { //awaitTermination 出現中斷異常也將觸發關閉 executorService.shutdownNow(); } }
可是實際使用中,可能會出現即便使用了shutdownNow
方法,仍是沒法終止線程的問題,那是由於你的線程沒法被中斷測試
shutdownNow
方法簡單理解就是給在運行的線程發一箇中斷信號,若是你的線程忽略這個信號,那就沒法停下來this
舉個例子來講明這個問題線程
public class ShutDownUtilsTest { private ExecutorService executorService; @Before public void init() { executorService = Executors.newFixedThreadPool(1); } @Test public void shutDownOKTest() { ShutDownUtils.waitUntilTerminate(executorService, 1); CommonUtils.sleep(1); //等待線程處理中斷 Assert.assertTrue(executorService.isTerminated()); } @Test public void shutDownNowFailTest() { executorService.execute(this::canNotStopThread); ShutDownUtils.waitUntilTerminate(executorService, 0); CommonUtils.sleep(1); //等待線程處理中斷 Assert.assertFalse(executorService.isTerminated()); } @Test public void shutDownNowOKTest() { executorService.execute(this::stopThread); ShutDownUtils.waitUntilTerminate(executorService, 0); CommonUtils.sleep(1); //等待線程處理中斷 Assert.assertTrue(executorService.isTerminated()); } private void canNotStopThread() { for (long i = 0; i < Long.MAX_VALUE; i++) { } } private void stopThread() { for (long i = 0; i < Long.MAX_VALUE && !Thread.currentThread().isInterrupted(); i++) { } } }
從上面的測試用例能夠看到canNotStopThread
沒法被shutDownNow
終止code
然而stopThread
能夠被正常終止,由於經過Thread.currentThread().isInterrupted()
在判斷線程是否收到了中斷信號it