异步运行列表中的所有元素(未知大小)

发布于 2025-02-04 05:49:05 字数 2753 浏览 1 评论 0原文

我正在尝试运行异步代码块的列表。我在旧线程中找到了一些帮助。不一致,向我展示并非所有异步结果都按预期完成。

在此示例代码中,我准备了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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

裸钻 2025-02-11 05:49:05

您的问题是您在所有期货中使用物理上相同的列表,因此取决于未来执行的时间 - 它将看到不同的数组状态,您需要创建单独的副本,例如:

final List<Integer> finalInts = ints.stream().toList();
System.out.println(String.format("Input ints: %s", finalInts));
CompletableFuture<List<Integer>> future =
        CompletableFuture.supplyAsync(
                () -> {
                    return finalInts;
                });

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:

final List<Integer> finalInts = ints.stream().toList();
System.out.println(String.format("Input ints: %s", finalInts));
CompletableFuture<List<Integer>> future =
        CompletableFuture.supplyAsync(
                () -> {
                    return finalInts;
                });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文