Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

    • Java并发概述
    • 线程与进程
    • Thread类与线程生命周期
    • 线程创建与任务模型
    • 线程安全
    • synchronized关键字
    • volatile关键字
    • Java内存模型(JMM)
    • 线程间通信
    • 线程池
    • 并发工具类
    • 原子操作类Atomic
    • 并发锁
    • 并发容器
    • ConcurrentHashMap
    • BlockingQueue
    • CopyOnWriteArrayList
    • ThreadLocal
    • Fork/Join框架
      • 1. 分治模型
      • 2. 核心类
      • 3. RecursiveTask 示例
      • 4. 工作窃取
      • 5. 阈值选择
      • 6. 与普通线程池区别
      • 7. 并行流关系
      • 专家实践与边界
      • Tips 快问快答
    • ScheduledThreadPoolExecutor
    • CompletableFuture
    • 虚拟线程
    • 死锁活锁与线程问题排查
    • 并发编程最佳实践
  • Java IO

  • JVM

  • Java
  • Java并发
Wray
2026-06-24
目录

Fork/Join框架

Fork/Join 是 Java 7 引入的并行计算框架,适合把大任务递归拆分成小任务并行执行,再合并结果。它常用于分治算法和并行流底层执行。

# 1. 分治模型

大任务
├─ 子任务 A
│  ├─ A1
│  └─ A2
└─ 子任务 B
   ├─ B1
   └─ B2

fork 拆分 -> 并行执行 -> join 合并

适合任务:

  • 可递归拆分。
  • 子任务相互独立。
  • 合并成本可控。
  • CPU 密集型为主。

# 2. 核心类

类 作用
ForkJoinPool 执行 ForkJoin 任务的线程池
RecursiveTask<V> 有返回值任务
RecursiveAction 无返回值任务
ForkJoinTask 任务基类

# 3. RecursiveTask 示例

public class SumTask extends RecursiveTask<Long> {
    private static final int THRESHOLD = 1000;
    private final long[] array;
    private final int start;
    private final int end;

    public SumTask(long[] array, int start, int end) {
        this.array = array;
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        if (end - start <= THRESHOLD) {
            long sum = 0;
            for (int i = start; i < end; i++) {
                sum += array[i];
            }
            return sum;
        }

        int mid = (start + end) >>> 1;
        SumTask left = new SumTask(array, start, mid);
        SumTask right = new SumTask(array, mid, end);
        left.fork();
        long rightResult = right.compute();
        long leftResult = left.join();
        return leftResult + rightResult;
    }
}

执行:

ForkJoinPool pool = new ForkJoinPool();
Long result = pool.invoke(new SumTask(array, 0, array.length));

# 4. 工作窃取

每个工作线程维护自己的双端队列。

Worker A deque: [A1, A2, A3]
Worker B deque: []

Worker B 空闲
  │
  ▼
从 Worker A 队列尾部窃取任务

工作窃取减少线程空闲,提高 CPU 利用率。

# 5. 阈值选择

任务拆得太大:并行度不足。任务拆得太小:调度开销过高。

总时间 = 计算时间 + 拆分成本 + 调度成本 + 合并成本

阈值需要压测决定,不存在通用值。

# 6. 与普通线程池区别

对比项 ForkJoinPool ThreadPoolExecutor
任务模型 递归拆分和合并 独立任务队列
调度 工作窃取 工作队列
适合 分治计算 通用异步任务
阻塞任务 不适合长阻塞 可按场景配置

ForkJoinPool 不适合大量阻塞 IO 任务。

# 7. 并行流关系

parallelStream() 默认使用公共 ForkJoinPool。

list.parallelStream()
        .map(this::calculate)
        .toList();

注意:

  • 公共池被阻塞会影响其他并行流。
  • 不要在并行流里做长时间阻塞 IO。
  • 不要修改共享可变状态。

# 专家实践与边界

ForkJoin 适合把大任务递归拆成小任务,再利用工作窃取提升 CPU 利用率。它不是通用异步线程池,更不适合大量阻塞 IO。

大任务
  ├─ 子任务 A
  │  ├─ A1
  │  └─ A2
  └─ 子任务 B
     ├─ B1
     └─ B2

工作线程空闲时从其他队列尾部窃取任务
场景 是否适合 原因
大数组并行计算 适合 可拆分、CPU 密集
递归搜索 适合 子任务结构自然
批量 RPC 不适合 阻塞 IO 占用工作线程
小任务过多 谨慎 拆分和调度成本可能超过收益
有共享写状态 谨慎 合并结果要设计清楚

任务拆分粒度是性能关键。拆得太粗并行度不够,拆得太细调度成本高。实际项目要通过阈值和压测调整。

# Tips 快问快答

Q:Fork/Join 适合什么任务? A:可拆分、可合并、子任务独立的 CPU 密集型任务。

Q:RecursiveTask 和 RecursiveAction 区别? A:前者有返回值,后者无返回值。

Q:工作窃取是什么? A:空闲线程从其他线程任务队列中偷任务执行。

Q:阈值怎么设置? A:通过压测平衡拆分开销和并行收益。

Q:ForkJoinPool 适合阻塞 IO 吗? A:通常不适合。

Q:parallelStream 用的是什么线程池? A:默认使用公共 ForkJoinPool。

Q:并行流一定更快吗? A:不一定,任务太小或有阻塞时可能更慢。

Q:fork 后一定要 join 吗? A:需要获取结果或确保完成时要 join,否则任务结果无法合并。

上次更新: 2026/06/25, 14:19:18
ThreadLocal
ScheduledThreadPoolExecutor

← ThreadLocal ScheduledThreadPoolExecutor→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式