2011-10-13 4 views

答えて

19

行くを取得する必要がありますいくつかの例を使用すると、タスクA, B, C, D, Eのセットを持っていたし、あなたがExecutorで非同期的にそれらのそれぞれを実行して、結果に1を処理したいとしています1が完了すると、 Executor

、あなたは次のようにそうするでしょう:

List<Future<?>> futures = new ArrayList<Future<?>>(); 
futures.add(executorService.submit(A)); 
futures.add(executorService.submit(B)); 
futures.add(executorService.submit(C)); 
futures.add(executorService.submit(D)); 
futures.add(executorService.submit(E)); 

//This loop must process the tasks in the order they were submitted: A, B, C, D, E 
for (Future<?> future:futures) { 
    ? result = future.get(); 
    // Some processing here 
} 

この方法の問題点は、タスクAが最初に完了するという保証がないことです。したがって、メインスレッドは、別のタスク(例えば、タスクB)の結果を処理することができるときに、タスクAが完了するのを待って空いているとブロックする可能性があります。 ExecutorCompletionServiceを使用すると、結果処理の待ち時間を短縮できます。

List<Future<?>> futures = new ArrayList<Future<?>>(); 
futures.add(executorCompletionService.submit(A)); 
futures.add(executorCompletionService.submit(B)); 
futures.add(executorCompletionService.submit(C)); 
futures.add(executorCompletionService.submit(D)); 
futures.add(executorCompletionService.submit(E)); 

//This for loop will process the tasks in the order they are completed, 
//regardless of submission order 
for (int i=0; i<futures.size(); i++) { 
    ? result = executorCompletionService.take().get(); 
    // Some processing here 
} 

タスクの結果を処理する順序は重要ではありませんときに、本質的には、ExecutorCompletionServiceはもう少し効率を絞り出すために使用することができます。

ただし、重要な点は1つです。 ExecutorCompletionServiceの実装には、結果のキューが含まれています。 takeまたはpollがそのキューを排水するために呼び出されない場合、メモリリークが発生します。一部の人々はsubmitによって返されたFutureを使用して結果を処理しますが、これは正しい使用法ではありません。

+0

正しい使い方はあなた自身を将来作成することです; – bestsss

+1

あなたのサポートのためにたくさんのTimありがとうございます。例と説明は明瞭です。 –

+0

そのような驚くべき答えと今のところわずか18票を得ました。これはちょうど私を悲しくする。その幼児はあなたの手でとてもかわいく見えます。 –

関連する問題