首页 > 解决方案 > 带有 .forEach 和 .add 的 Java ForkJoinPool

问题描述

我有一个对象列表TicketDTO,每个对象都TicketDTO需要通过一个函数将数据转换为TicketDataDTO. 我在这里想要的是减少运行此代码所需的时间,因为当列表大小较大时,转换它需要很长时间,并且通过 GET 映射获取数据是不可接受的。但是,当我尝试ForkJoinPoolparallelStream)(下面的代码)一起实现以完成它时,我的返回 List` 是空的。有人可以告诉我我做错了什么吗?

@Override
public List<TicketDataDTO> getOtrsTickets(String value, String startDate, String endDate, String product, String user) {
  // TODO Implement threads
  List<TicketDTO> tickets = ticketDao.findOtrsTickets(value, startDate, endDate, product, user);
  Stream<TicketDTO> ticketsStream = tickets.parallelStream();
  List<TicketDataDTO> data = new ArrayList<TicketDataDTO>();
  
  ForkJoinPool forkJoinPool = new ForkJoinPool(6);
  
  forkJoinPool.submit(() -> {
    try {
      ticketsStream.forEach(ticket -> data.add(createTicketData(ticket)));
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  });
  
  forkJoinPool.shutdown();
  
  //ticketsStream.forEach(ticket -> data.add(createTicketData(ticket)));

  return data;

createTicketData只是一个带有两个 for 循环和一个 switch 循环的函数,用于创建我需要的一些新列作为输出。

标签: javaarraysspring-bootthreadpoolparallel.foreach

解决方案


除了调用shutdown()ForkJoinPool 之外,您还必须等待它的终止,例如

forkJoinPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);

如果不等待终止,data将在线程有机会将其结果添加到它之前返回。

请参阅 如何使用 ExecutorService 等待所有线程完成? 更多细节


推荐阅读