异步运行列表中的所有元素(未知大小)
我正在尝试运行异步代码块的列表。我在旧线程中找到了一些帮助。不一致,向我展示并非所有异步结果都按预期完成。
在此示例代码中,我准备了list< pountableFuture< list< integer>>>
。该列表包含一堆我想一次收集的期货,而无需一次等待。每个异步块都将当前整数列表复制到新列表中。
List<CompletableFuture<List<Integer>>> futureList = new ArrayList<>();
List<Integer> ints = new ArrayList<>();
for (int i=0; i<50; i++) {
ints.add(Integer.valueOf(i));
if (ints.size() < 5) {
continue;
}
System.out.println(String.format("Input ints: %s", ints));
CompletableFuture<List<Integer>> future =
CompletableFuture.supplyAsync(
() -> {
return new ArrayList<>(ints);
});
futureList.add(future);
ints.clear();
}
输出是
Input ints: [0, 1, 2, 3, 4]
Input ints: [5, 6, 7, 8, 9]
Input ints: [10, 11, 12, 13, 14]
Input ints: [15, 16, 17, 18, 19]
Input ints: [20, 21, 22, 23, 24]
Input ints: [25, 26, 27, 28, 29]
Input ints: [30, 31, 32, 33, 34]
Input ints: [35, 36, 37, 38, 39]
Input ints: [40, 41, 42, 43, 44]
Input ints: [45, 46, 47, 48, 49]
接下来的预期,我想收集每个未来的结果。代码是
try {
CompletableFuture<List<List<Integer>>> allInts = CompletableFuture
.allOf(futureList.toArray(new CompletableFuture[0]))
.thenApply(v ->
futureList.stream().map(CompletableFuture::join).collect(Collectors.toList())
);
System.out.println(String.format("Output ints: %s", allInts.get()));
} catch (Exception e) {
throw new RuntimeException(e);
}
输出不一致。有时,没有一个INT列表出现,有时会出现其中一些。示例结果:
Output ints: [[15, 16, 17, 18, 19], [25, 26, 27, 28, 29], [15, 16, 17, 18, 19], [15, 16, 17, 18, 19], [25, 26, 27, 28, 29], [30, 31, 32, 33, 34], [35, 36, 37, 38, 39], [40, 41, 42, 43, 44], [45, 46, 47, 48, 49], []]
------------
Output ints: [[10, 11, 12, 13, 14], [20, 21, 22, 23, 24], [10, 11, 12, 13, 14], [20, 21, 22], [25, 26, 27, 28, 29], [30, 31, 32, 33, 34], [35, 36, 37, 38, 39], [40, 41, 42, 43, 44], [45, 46, 47, 48, 49], []]
------------
Output ints: [[10, 11, 12, 13, 14], [10, 11, 12, 13, 14], [10, 11, 12, 13, 14], [35, 36, 37, 38, 39], [], [], [], [], [], []]
很明显,即使我在.alof().allof()
结果上运行.thenapply()
,也不是所有的期货正在完成。我怀疑.allof()
输入不正确,但我不确定。任何帮助都会很棒。
I am trying to run a list of asynchronous code blocks. I found some help in older threads, but the results are inconsistent and show me that not all asynchronous results are completing as expected.
In this sample code, I prepare a List<CompletableFuture<List<Integer>>>
. The list contains a bunch of futures that I want to collect all at once, without waiting one at a time. Each async block just copies the current list of Integers into a new list.
List<CompletableFuture<List<Integer>>> futureList = new ArrayList<>();
List<Integer> ints = new ArrayList<>();
for (int i=0; i<50; i++) {
ints.add(Integer.valueOf(i));
if (ints.size() < 5) {
continue;
}
System.out.println(String.format("Input ints: %s", ints));
CompletableFuture<List<Integer>> future =
CompletableFuture.supplyAsync(
() -> {
return new ArrayList<>(ints);
});
futureList.add(future);
ints.clear();
}
The output is as expected
Input ints: [0, 1, 2, 3, 4]
Input ints: [5, 6, 7, 8, 9]
Input ints: [10, 11, 12, 13, 14]
Input ints: [15, 16, 17, 18, 19]
Input ints: [20, 21, 22, 23, 24]
Input ints: [25, 26, 27, 28, 29]
Input ints: [30, 31, 32, 33, 34]
Input ints: [35, 36, 37, 38, 39]
Input ints: [40, 41, 42, 43, 44]
Input ints: [45, 46, 47, 48, 49]
Next, I want to collect the results of each future. The code is
try {
CompletableFuture<List<List<Integer>>> allInts = CompletableFuture
.allOf(futureList.toArray(new CompletableFuture[0]))
.thenApply(v ->
futureList.stream().map(CompletableFuture::join).collect(Collectors.toList())
);
System.out.println(String.format("Output ints: %s", allInts.get()));
} catch (Exception e) {
throw new RuntimeException(e);
}
The output is inconsistent. Sometimes none of the int lists show up, sometimes some of them show up. Sample results:
Output ints: [[15, 16, 17, 18, 19], [25, 26, 27, 28, 29], [15, 16, 17, 18, 19], [15, 16, 17, 18, 19], [25, 26, 27, 28, 29], [30, 31, 32, 33, 34], [35, 36, 37, 38, 39], [40, 41, 42, 43, 44], [45, 46, 47, 48, 49], []]
------------
Output ints: [[10, 11, 12, 13, 14], [20, 21, 22, 23, 24], [10, 11, 12, 13, 14], [20, 21, 22], [25, 26, 27, 28, 29], [30, 31, 32, 33, 34], [35, 36, 37, 38, 39], [40, 41, 42, 43, 44], [45, 46, 47, 48, 49], []]
------------
Output ints: [[10, 11, 12, 13, 14], [10, 11, 12, 13, 14], [10, 11, 12, 13, 14], [35, 36, 37, 38, 39], [], [], [], [], [], []]
It's clear that not all of the futures are completing, even though I am running .thenApply()
on the .allOf()
result. I suspect something is incorrect with the .allOf()
input, but I am not sure. Any help would be great.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题是您在所有期货中使用物理上相同的列表,因此取决于未来执行的时间 - 它将看到不同的数组状态,您需要创建单独的副本,例如:
your problem is that you're using the physically the same list in all futures, so depending on time when future is executed - it will see different state of array, you need to create separate copy, for example like this: