使用

2016-07-19 11 views
0

私はFutures 使用

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

または

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

を使用していた場合、システムが完了するのタスクを待ちます。

上記のステートメントの後にexecutorService.shutdownNow();があったとしても、システムはいつもシステム上の既存のスレッドを強制的に終了させるのか分からないので、システムは決してその行が完了するまで未来はに返されます。 何か不足していますか?それをテストする別のテストケースシナリオはありますか?

will shutdownNowは、Runnableとしか動作しません。つまり、 executorService.submit(new MyRunnable())

EDIT:

私はいくつかの異なるものを試してみました

A)shutdownNowinvokeAllでは動作しないことが分かりました。 Future.get then文shutdownNowがブロックされFutureまではCallableの場合(解決された後に存在する場合

B)shutdownNow)。

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"; 
    } 

} 

と、次のように私はそれをテストしてい:

タスクはすべて Callablesある
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(); 

ボトムラインはinvokeAllFuture.getです。誰かが妥当性を確認できますか?

+2

'shutdownNow'は、あなたが対応する' ExecutorService'に送信した作業を実行するスレッドを停止しようとします。おそらく、 'Future#get()'を行う別々のスレッドがあります。 –

+1

"強制終了しますか?"例えば、典型的な実装はThread.interrupt()を介して取り消されるため、割り込みに応答しないタスクは決して終了しないかもしれません" –

答えて

1

CallableあなたがThreadPoolExecutorに投稿したものは、java.util.concrrent.FutureTaskとラップされて実行されます。この場合

、タスクがThread.sleep(10000)によってブロックされたときSingleRunnableWorkerSingleCallableWorkerの両方で、executorService.shutdownNow()はInterruptedExceptionあるが、すぐにスローさせます。

しかし、

  • InterruptedExceptionSingleRunnableWorker.run()でスローはすぐcatchedとe.printStackTrace()が扱うことを余儀なくさ です。SingleCallableWorker.call()でスロー
  • InterruptedExceptionは 、FutureTaskにインナーsyncronizerによってsyncronizerだけ 記録InterruptedExceptionあるとリターンをcatchedされます。 future.get()が呼び出されると、 InterruptedExceptionがExecutionExceptionとしてラップされ、 が再スローされます。