2017-06-01 47 views
1

我嘗試提交併在同一個流中獲得10 Future s。每個人都需要1秒的時間來處理,我想平行運行它們。如何在相同的Java流中正確提交併獲取多個期貨?

我的第一次嘗試是takes_10_sec(),它依次運行,需要10s。

我的第二次嘗試是takes_1_sec()它並行運行並需要1秒。然而它使用中間的.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

流是懶惰的,只會根據終端操作的需要處理元素。對於每個元素,整個管道在開始處理下一個元素之前(並行流除外)。例如,該技術允許短路操作。

由於您有一箇中間的map()操作會阻止創建的未來結果,因此處理它將等待每個將來完成,然後再創建下一個未來。

收集所有這些信息確保所有的期貨都是先創建的。這是適當的解決方案,因爲您需要確保在處理結果之前處理整個流。

相關問題