【问题标题】:How to perform the transformation on CompletableFuture tasks如何对 CompletableFuture 任务执行转换
【发布时间】:2020-12-27 12:33:06
【问题描述】:

我正在尝试对 CompletableFuture 任务列表执行一些转换,但由于缺乏经验而面临一些问题。我有一个 CompletableFuture 列表,但我无法对其执行进一步的转换。

import java.util.*;

import java.util.concurrent.CompletableFuture;

import java.util.concurrent.ExecutionException;

public class thenapply {

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        List<Integer> list = Arrays.asList(5, 9, 14);

        final int sum = 0;

        List<CompletableFuture<Integer>> ans = new ArrayList<>();

        for (int i = 0; i < list.size(); i++) {

            final int finali = i;

            ans.add(CompletableFuture.supplyAsync(() -> square(list.get(finali))));

        }

        System.out.println(ans.stream()

                .mapToInt(Integer::intValue).sum());

    }

    private static int square(int a) {

        return a * a;

    }

}

我知道.mapToInt(Integer::intValue) 错了,但不知道如何改正。此外,我读到我们应该使用allOf,但我不确定如何在这里实现它。

请帮忙。

【问题讨论】:

  • numerous methods you can use。例如,可能是jointhenAcceptthenAcceptAsync 等。
  • .mapToInt(CompletableFuture::join) 但您应该知道,使用CompletableFuture 执行这种粒度的并行操作效率低下,编写起来也很复杂。

标签: java java-8 concurrency


【解决方案1】:
public static void main(String[] args) throws InterruptedException, ExecutionException {
    List<Integer> list = Arrays.asList(5, 9, 14);
    final AtomicInteger sum = new AtomicInteger(0);
    int size = list.size();
    CountDownLatch latch = new CountDownLatch(size);
    for (int i = 0; i < size; i++) {
        final int finali = i;
        CompletableFuture.runAsync(() -> {
            int sq= square(list.get(finali));
            sum.addAndGet(sq);
            latch.countDown();
        });
    }
    latch.await();
    System.out.println(sum.get());
}

【讨论】:

  • 为什么我们需要使用CountDownLatch ans.stream().mapToInt(data-&gt;data.join).sum() 怎么样?它有效,但想确定我是否要使用 allOf 并处理异常?
  • join() 是阻塞操作,不应该在异步代码中使用。另请参阅@Holger 的评论
  • 如果我理解正确,System.out.println(sum.get());将等到latch.countDown();值为零,即线程中的所有任务都已完成。我收到unreported exception java.loang. InterruptedException: must be caught or declared to be thrown。我应该在latch.await() 之后在try 中添加整个代码块吗?
  • 您是否在 main() 的声明中添加了“throws InterruptedException”,就像我的文本中一样?
【解决方案2】:

您需要等待完成才能进行进一步的计算。 所以,与其上一个System.out.println,不如做点什么

// wait and process individual values
int result = 0;
for (var f : ans) {
    result += f.get();
}
System.out.println(result);

【讨论】:

  • error: incompatible thrown type InterruptedException, ExecutionException 最后一行。
  • @Amul123 我修改了我的答案以适应这一点并删除了不必要的步骤。
猜你喜欢
  • 2018-09-28
  • 1970-01-01
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
相关资源
最近更新 更多