我有一个输入元素列表,我想排队进入多个ThreadPools。假设这是我的输入:
final List<Integer> ints = Stream.iterate(1, i -> i + 1).limit(100).collect(Collectors.toList());
这些是我希望元素依次运行的三个功能:
final Function<Integer, Integer> step1 =
value -> { // input from the ints list
return value * 2;
};
final Function<Integer, Double> step2 =
value -> { // input from the previous step1
return (double) (value * 2); //
};
final Function<Double, String> step3 =
value -> { // input from the previous step2
return "Result: " + value * 2;
};
这些将是每个步骤的池:
final ExecutorService step1Pool = Executors.newFixedThreadPool(4);
final ExecutorService step2Pool = Executors.newFixedThreadPool(3);
final ExecutorService step3Pool = Executors.newFixedThreadPool(1);
我希望每个元素都贯穿step1Pool
并应用step1
。一旦完成一项要素,其结果应
最终以step2pool
结尾,因此可以在此处应用step2
。一旦完成step2Pool
中的操作,就应该
已在step3Pool
和step3
中排队。
在我的主线程上,我想等到获得step3
的所有结果。每个元素的处理顺序
没关系只有它们都在正确的线程池上通过step1
-> step2
-> step3
运行。
基本上,我想并行化Stream.map
,将每个结果立即推送到下一个队列,并等待直到
从我的上一个线程池中获得了ints.size()
的结果。
有没有一种简单的方法可以用Java实现?
答案 0 :(得分:4)
我相信CompletableFuture将在这里为您提供帮助!
List<CompletableFuture<String>> futures = ints.stream()
.map(i -> CompletableFuture.supplyAsync(() -> step1.apply(i), step1Pool)
.thenApplyAsync(step2, step2Pool)
.thenApplyAsync(step3, step3Pool))
.collect(Collectors.toList());
List<String> result = futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
答案 1 :(得分:0)
为此最好使用流:
List<String> stringList = Stream.iterate(1, i -> i + 1)
.limit(100)
.parallel()
.map(step1)
.map(step2)
.map(step3)
.collect(Collectors.toList());