2016-08-12 17 views
1

私は並行性が新しく、do-whileループの実行者サービスの同時実行性を実装しようとしていました。JavaのDo-WhileループのExecutorService

do {  
    Future<Void> future = executor.submit(new Callable<Void>() { 
    @Override   
    public Void call() throws Exception { 

     // action 
     return null; 
    } 
    }); 

    futures.add(future); 
    executor.shutdown(); 

    for (Future<Void> future : futures) { 
     try { 
      future.get(); 
     } 
     catch (InterruptedException e) { 
      throw new IOException(e) 
     }   
    } 
} 
while (true); 

しかし、これは間違っているようだ。しかし、私はいつもここに私のサンプルコードですRejectedExecutionException

に実行します。私は間違った場所でシャットダウンを呼びかけていると思う。誰でもExecutor Service in a do-whileループを正しく実装するのを助けてください。ありがとう。

答えて

3

ExecutorService.shutdown()は、これ以上ジョブを受け入れないようにします。ExecutorServiceあなたが仕事を提出し終わったら呼び出されるべきです。

Future.get()は、現在のスレッドの実行をブロックし、ループの次の繰り返しは、この未来(getが呼び出される)が返ってこない限り続行しません。これはすべての反復で発生し、コードを非並列にします。

CountDownLatchを使用すると、すべてのジョブが戻るのを待つことができます。

以下は正しいコードです。また

final List<Object> results = Collections.synchronizedList(new ArrayList<Object>()); 
final CountDownLatch latch = new CountDownLatch(10);//suppose you'll have 10 futures 

do { 
    Future<Void> future = executor.submit(new Callable<Void>() { 
     @Override 
     public Void call() throws Exception { 
      // action 
      latch.countDown();//decrease the latch count 
      results.add(result); // some result 
      return null; 
     } 
    }); 

    futures.add(future); 
} while (true); 

executor.shutdown(); 

latch.await(); //This will block till latch.countDown() has been called 10 times. 

//Now results has all the outputs, do what you want with them. 

あなたは、あなたがThreadPoolExecutorドキュメントからこの答えhttps://stackoverflow.com/a/36261808/5343269

+1

良かった点を。私の2セント:すべての未来が完了するのを待ってからそれらのいずれかを処理するのを待っていない限り、CountDownLatchは本当に必要*ではありません。重要なことは、ループ内でFuture.getを呼び出さないことです。ループの後に呼び出しが行われる限り、すぐには返されないかもしれません。これはラッチを待つのと同様の効果があります。 – dnault

+0

@dnaultあなたが正しいと思うかもしれませんが、別のエグゼキューターサービスは、すぐに結果を処理するのに使うことができます。 'Future.get()'を使ってブロックすると信頼できなくなります。リストの最初の未来があると、完了したすべての結果を待つことになります。 – 11thdimension

1

正しいです、shutdownメソッドが正しい時刻に呼び出されていません。 ExecutorServiceは、shutdownが呼び出された後でタスクを受け付けません(あなた自身のバージョンを実装していない限り)。

executorにすべてのタスクを既に提出した後は、shutdownに電話する必要があります。この場合は、do-whileのループの後になります。

0

を見てとることができたJava 8で作業している場合:に提出

新しいタスクを

拒否されたタスクエグゼキュータがシャットダウンされたとき、およびExecutorが最大スレッドとワークキューの両方の容量に有限の境界を使用するときに、メソッドexecute(Runnable)は拒否されます。飽和している。いずれの場合も

、executeメソッドは、あなたのコードから RejectedExecutionHandler.rejectedExecution(Runnable, ThreadPoolExecutor) method of its RejectedExecutionHandler

を呼び出し、それはあなたが最初shutdown()を呼び出して、後でタスクを提出していることを明らかです。別のノートで

ExecutorServiceをシャットダウンする正しい方法については、この関連のSEの質問を参照してください。

ExecutorService's shutdown() doesn't wait until all threads will be finished

関連する問題