2016-07-19 33 views
0

使用shutdownNow時。如果我使用Futures在並行框架

List<Future<String>> results = executorService.invokeAll(tasks); 

Future<String> res = executorService.submit(new SingleWorker()); 
System.out.println(res.get()); 

系統等待的任務來完成。

即使我有executorService.shutdownNow();上述聲明後,我真的不作爲,因爲文件中提到的理解時將系統強行終止現有的線程,直到任務完成的系統永遠不會到達線和未來返回。 我錯過了什麼?是否有不同的測試用例場景來測試它?

shutdownNow只與Runnable工作,即當我們說 executorService.submit(new MyRunnable())

編輯:

我嘗試一些不同的東西,發現了

一)shutdownNowinvokeAll工作。

b)中shutdownNow如果存在後Future.get那麼語句shutdownNow被阻塞直到Future被解決(在Callable的情況下)。

c)shutdownNowRunnable完美配合。

下面是我編寫的代碼進行測試:

class SingleRunnableWorker implements Runnable { 

    @Override 
    public void run() { 
     System.out.println("SingleRunnableWorker Running.."); 
     try { 
      Thread.sleep(10000); 
      System.out.println("SingleRunnableWorker Running after sleep.."); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

class SingleCallableWorker implements Callable<String> { 

    @Override 
    public String call() throws Exception { 
     System.out.println("SingleCallableWorker Calling.."); 
     Thread.sleep(10000); 
     System.out.println("SingleCallableWorker Calling after sleep.."); 
     return "SingleCallableWorker Calling done"; 
    } 

} 

,我如下測試它:

ExecutorService executorService = Executors.newFixedThreadPool(4); 
/*List<Future<String>> results = */executorService.invokeAll(tasks);//blocks by default 

Future<String> res = executorService.submit(new SingleCallableWorker()); 
//System.out.println(res.get()); //blocks if uncommented 

executorService.submit(new SingleRunnableWorker()); 

executorService.shutdownNow(); 

其中任務都Callables

底線是invokeAllFuture.get是阻止操作。有人可以驗證嗎?

+2

'shutdownNow'將嘗試停止執行您提交給相應的'ExecutorService'的工作的線程。據推測,有單獨的線程執行'Future#get()'。 –

+1

「強行終止?」不是真的,請閱讀文檔:「除了盡力而爲的嘗試停止處理主動執行的任務之外,沒有任何保證,例如,典型的實現將通過Thread.interrupt()取消,所以任何未能響應中斷的任務都可能永遠不會終止「。 –

回答

1

您提交給ThreadPoolExecutorRunnbaleCallable都將被包裝爲java.util.concrrent.FutureTask並執行。

在這種情況下,在SingleRunnableWorkerSingleCallableWorker,當任務由Thread.sleep(10000)受阻,executorService.shutdownNow()會造成InterruptedException異常立即拋出。

但是,

  • InterruptedExceptionSingleRunnableWorker.run()拋出是 被迫立即獲取,並通過e.printStackTrace()處理。
  • InterruptedException丟在SingleCallableWorker.call()將 被FutureTask內同步器捕獲,同步器只是 記錄InterruptedException並返回。當調用future.get()時, InterruptedException將被重新包裝爲ExecutionException並重新拋出 。