2011-05-10 10 views
4

我的代碼:的Java:ExecutorService的線程組停止


String[] torrentFiles = new File("/root/torrents/").list(); 

     if(torrentFiles.length == 0 || torrentFiles == null) 
     { 
      System.exit(0); 
     } 

     ex = Executors.newFixedThreadPool(3); 

     for(String torrentFile : torrentFiles) 
     { 
      ex.submit(new DownloadTorrent("/root/torrents/" + torrentFile)); 
     } 

     ex.shutdown(); 

     try 
     { 
      ex.awaitTermination(30, TimeUnit.MINUTES); 
     } 
     catch(InterruptedException ex1) 
     { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex1); 
     } 

但有時洪流下載需要未知的時間價值和«awaitTermination»沒有作品我想要的。我需要在半小時後立即停止所有執行的線程,但正如我所知,「awaitTermination」只是使用interrupt()方法,該方法只能在循環或等待中使用。所以如果這一刻發生,暫停不起作用。那麼,如何?

回答

6

ExecutorService.shutdownNow()將嘗試停止所有正在執行的線程..

這裏是javadoc的報價

List<Runnable> shutdownNow()

嘗試停止所有正在 執行任務,暫停處理 等待任務,並返回正在等待 執行的任務列表 。

除了竭盡全力嘗試阻止 處理主動執行任務之外,沒有任何保證 。例如,典型的實現 將通過Thread.interrupt()取消,所以如果任何任務屏蔽或未能響應 中斷,則它們可能永遠不會終止。

+1

我也使用shutdownNow()來停止所有其他正在執行的線程,但我能夠停止正在等待服務響應的線程。如果我讓線程進入休眠狀態,那麼它會立即停止,但在前一種情況下它不會。這有什麼特別的原因嗎? – Akshay 2015-02-26 23:08:49

+0

@Akshay - 是的,這是有理由發生的。 Thread.sleep()檢查中斷狀態,如果線程已經中斷,則它會拋出InterruptedException。但是,如果沒有發生這種阻塞事件,正如文檔中提到的那樣,除了竭盡全力嘗試停止處理主動執行的任務之外,沒有任何保證。 – skm 2017-07-15 16:41:45

1

ExecutorService.submit(...)返回具有cancel()方法的Future<?>。你應該跟蹤這些可以調用它,當你想要停止每個任務。

+8

如果他在他的實現中沒有對Thread.interrupted()進行檢查,這將不起作用。 – pintxo 2011-05-10 07:51:08

7

除非線程定期檢查isInterrupted()標誌(或正在以可中斷方法等待,即拋出InterruptedException),否則不會保證即時線程終止。

當他們定期檢查isInterrupted()時,考慮以方式實現您的工作線程。這可能是類似的東西:

public void run() { 
    byte[] data; 
    do { 
    data = receiveDataChunk(timeout); 
    processData(data); 
    } while(!isInterrupted() && data != null); 
} 
-1

現在我必須停止池中的線程。我正在這樣做。這可能不是一個好主意。請評論,如果是的話。

boolean isTerminated = mPoolThreads.isTerminated(); 
while (!isTerminated) { 
    mPoolThreads.shutdownNow(); 
    isTerminated = mPoolThreads.isTerminated(); 
    Log.i(Constants.LOG_TAG, "Stop threads: the threads are not terminated yet"); 
} 
Log.w(Constants.LOG_TAG, "Stop threads: Terminated"); 
+0

我不確定直接問題,但不是「while」循環,而是在這種情況下更好的模式(在你看不到終止代碼的情況下你不能說明)就是說例如'for(int retries = 0; retries <1000; ++ retries)'。另外,在重試之間添加10 ms的等待時間,或者至少['yield()'](http://stackoverflow.com/a/6979859/1143274)。如果達到1000,則記錄一個錯誤。 (而不是1000,它應該是一個很大的數字,如果它表現正確,那麼完全不合理。) – 2016-02-28 08:23:29

0

上午使用此代碼我已創建。

它從許多html模板使用wkhtmltopdf生成許多PDF文件。

所以我想提高性能創建handreds沒有保持客戶端等待,這只是實施的一部分。

getListOfCallables它返回正確的最佳 閾值的線程#用於固定池創建。

所以我不能處理大量的非死線鋪設在它使我的EC2 CPU 100%卡住了。

我使用:

  • 關閉()
  • 執行shutdownNow()中的其他的等待
  • 執行shutdownNow()中的異常部分

列表fileGenerationHtmlToPdfList = getListOfCallables(路徑名稱,選項);

  ExecutorService executorService = Executors.newFixedThreadPool(fileGenerationHtmlToPdfList.size()); 


      List<Future<ArrayList<File>>> futures = null; 

      try { 
       futures = executorService.invokeAll(fileGenerationHtmlToPdfList); 
       try { 
        for(Future f: futures) { 
         files.addAll((ArrayList<File>)f.get()); 
        } 

       } catch (InterruptedException ex) { 
        Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex); 
       } catch (ExecutionException ex) { 
        Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex); 
       } 
      } catch (InterruptedException ex) { 
       Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex); 
      } 

executorService.shutdown();//try shutdown 

      try { 
       if (executorService.awaitTermination(5, TimeUnit.SECONDS)) { 
        Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Done ShutDowned"); 
       } else { 
        executorService.shutdownNow(); 
       } 
      } catch (InterruptedException ex) { 
       executorService.shutdownNow(); 
       Logger.getLogger(FileUtil.class.getName()).log(Level.SEVERE, "Interrupted Exception " , ex); 
      }