2023-03-22  阅读(7)
原文作者:简单教程 原文地址:https://www.twle.cn/c/yufei/javatm/javatm-basic-executorservice.html

ForkJoinPool 是Java 7 中引入的 fork/join 框架的核心之一。它解决了一个常见的问题: 如何在递归中生成多个任务。因为,即使是使用一个简单的 ThreadPoolExecutor ,也会在不断的递归中快速耗尽线程。因为每个任务或子任务都需要自己的线程来运行。

在 fork/join 框架中,任何任务都可以生成 ( fork ) 多个子任务并使用 join() 方法等待它们的完成。fork/join 框架的好处是它不会为每个任务或子任务创建新线程,而是实现了 工作窃取 ( Work Stealing ) 算法。关于 fork/join 框架的详细信息,你可以访问我们的 一文秒懂 Java Fork/Join。

接下来,我们看一个使用 ForkJoinPool 遍历节点树并计算所有叶值之和的简单示例。在这个示例中,树是一个由节点,int 值和一组子节点组成。

    static class TreeNode {
    
        int value;
    
        Set<TreeNode> children;
    
        TreeNode(int value, TreeNode... children) {
            this.value = value;
            this.children = Sets.newHashSet(children);
        }
    }

创建了树 TreeNode 之后,如果我们想要并行地对树中的所有值求和,我们需要实现一个 RecursiveTask<Integer> 接口。每个任务都接收自己的节点,并将其值添加到其子节点的值之和上。

要计算子节点值的总和,任务实现执行以下操作

  1. 将子节点集合转换为流 ( stream )
  2. 映射前面操作中创建的流,为每个元素创建一个新的 CountingTask
  3. 通过 fork 执行每个子任务
  4. 通过在每个 fork 任务上调用 join() 方法来收集结果
  5. 使用 ·Collectors.summingInt` 收集器对结果求和
    public static class CountingTask extends RecursiveTask<Integer> {
    
        private final TreeNode node;
    
        public CountingTask(TreeNode node) {
            this.node = node;
        }
    
        @Override
        protected Integer compute() {
            return node.value + node.children.stream()
              .map(childNode -> new CountingTask(childNode).fork())
              .collect(Collectors.summingInt(ForkJoinTask::join));
        }
    }

在树上运行计算的代码非常简单:

    TreeNode tree = new TreeNode(5,
      new TreeNode(3), new TreeNode(2,
        new TreeNode(2), new TreeNode(8)));
    
    ForkJoinPool forkJoinPool = ForkJoinPool.commonPool();
    int sum = forkJoinPool.invoke(new CountingTask(tree));

Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文