1

私は提出しようとし、同じストリーム内に10 Futureを取得しようとします。それぞれの処理に1秒かかるので、並列に実行したいと思います。同じJavaストリームで複数のFuturesを適切に提出して取得するにはどうすればいいですか?

私の最初の試行はtakes_10_sec()で、これは連続して実行され、10秒かかる。

私の2回目の試行は、並行して実行され、1秒かかるtakes_1_sec()です。しかし、それは私がそれを行う良い方法だとは思わない中間.collect(Collectors.toList()).stream()を使用します。

別の推奨方法はありますか?

public class FutureStream { 
    private ExecutorService executor = Executors.newFixedThreadPool(10);; 

    @Test 
    public void takes_10_sec() { 
     IntStream.range(0, 10) 
       .mapToObj(i -> longTask()) 
       .map(task -> { 
        try { 
         return task.get(); 
        } catch (InterruptedException | ExecutionException e) { 
         throw new RuntimeException(e); 
        } 
       }) 
       .forEach(System.out::println); 
    } 

    @Test 
    public void takes_1_sec() { 
     IntStream.range(0, 10) 
       .mapToObj(i -> longTask()) 
       .collect(Collectors.toList()) 
       .stream() 
       .map(task -> { 
        try { 
         return task.get(); 
        } catch (InterruptedException | ExecutionException e) { 
         throw new RuntimeException(e); 
        } 
       }) 
       .forEach(System.out::println); 
    } 

    private Future<String> longTask() { 
     return executor.submit(() -> { 
      Thread.sleep(1000); 
      return Thread.currentThread().getName(); 
     }); 
    } 
} 

答えて

3

ストリームは遅延しており、ターミナル操作で必要に応じて要素を処理します。各要素に対して、パイプライン全体が次の要素で開始する前に処理されます(パラレルストリームを除く)。この技術は、例えば短絡動作を可能にする。

作成された未来の結果をブロックする中間の操作があるので、処理は未来が完了するのを待ってから次のものを作成します。

すべての先物が最初に作成されていることを確認してください。結果を処理する前にストリーム全体が処理されることを確認する必要があるので、これは適切なソリューションです。

関連する問題