2017-06-01 45 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()操作会阻止创建的未来结果,因此处理它将等待每个将来完成,然后再创建下一个未来。

收集所有这些信息确保所有的期货都是先创建的。这是适当的解决方案,因为您需要确保在处理结果之前处理整个流。

相关问题