Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • MacOS
  • Linux
  • Windows
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java基础

    • Java概述
    • Java语法
    • 面向对象编程
    • Java数组
    • String字符串
    • 异常处理
  • Java集合

    • Java集合概述
    • ArrayList
    • LinkedList
    • HashMap
    • LinkedHashMap
    • HashSet
    • TreeMap
    • Queue&Deque
  • Java并发

    • Java并发概述
    • 线程与进程
    • Thread类与线程生命周期
    • 线程安全
    • synchronized关键字
    • volatile关键字
    • Java内存模型(JMM)
    • 线程间通信
    • 线程池
    • 并发工具类
    • 原子操作类Atomic
    • 并发锁
    • 并发容器
    • ConcurrentHashMap
    • BlockingQueue
    • CopyOnWriteArrayList
    • ThreadLocal
    • Fork/Join框架
      • 1. Fork/Join 框架的基本概念
      • 2. Fork/Join 框架的核心类
        • 2.1 ForkJoinPool
        • 2.2 ForkJoinTask
        • 2.3 RecursiveTask 示例
      • 3. Fork/Join 框架的工作机制
      • 4. Fork/Join 框架的优缺点
      • 5. Fork/Join 框架的应用场景
      • 6. 与其他并发工具的比较
      • 7. 总结
    • ScheduledThreadPoolExecutor
    • CompletableFuture
  • Java IO

    • Java IO概述
  • JVM

    • JVM概述
  • Java
  • Java并发
Wray
2024-10-31
目录

Fork/Join框架

Fork/Join 框架是 Java 7 引入的一种并行计算框架,位于 java.util.concurrent 包中,主要用于将大任务拆分为多个小任务并行执行,从而充分利用多核 CPU 的性能。它是分治算法在并行编程中的一种典型实现,特别适合处理递归类型的问题。

# 1. Fork/Join 框架的基本概念

  • 分治思想:Fork/Join 框架的核心思想是将一个大任务分解为多个小任务(Fork),然后并行地执行这些小任务,最后合并结果(Join)。
  • 工作窃取算法:Fork/Join 框架采用工作窃取算法(Work Stealing Algorithm),即空闲的工作线程会主动寻找其他忙碌线程的任务队列中的未执行任务,从而提高 CPU 的利用率。

# 2. Fork/Join 框架的核心类

# 2.1 ForkJoinPool

  • 概念:ForkJoinPool 是 Fork/Join 框架的执行器,用于管理和调度任务。它维护了多个工作线程,以实现任务的并行执行。
  • 线程管理:ForkJoinPool 会根据任务的工作量和系统的硬件情况,动态调整工作线程的数量,确保高效利用系统资源。
  • 示例代码:
    ForkJoinPool forkJoinPool = new ForkJoinPool();
    MyRecursiveTask task = new MyRecursiveTask(0, 1000);
    Integer result = forkJoinPool.invoke(task);
    System.out.println("Result: " + result);
    

# 2.2 ForkJoinTask

  • 概念:ForkJoinTask 是 Fork/Join 框架中的抽象基类,定义了任务的基本行为,是所有任务的父类。
  • 直接子类:ForkJoinTask 有两个直接子类:RecursiveTask 和 RecursiveAction。
    • RecursiveTask<V>:适用于有返回值的任务,泛型 V 表示返回值的类型。
    • RecursiveAction:适用于没有返回值的任务。

# 2.3 RecursiveTask 示例

  • RecursiveTask 使用示例:
    public class MyRecursiveTask extends RecursiveTask<Integer> {
        private final int threshold = 100;
        private int start;
        private int end;
    
        public MyRecursiveTask(int start, int end) {
            this.start = start;
            this.end = end;
        }
    
        @Override
        protected Integer compute() {
            if (end - start <= threshold) {
                int sum = 0;
                for (int i = start; i <= end; i++) {
                    sum += i;
                }
                return sum;
            } else {
                int middle = (start + end) / 2;
                MyRecursiveTask leftTask = new MyRecursiveTask(start, middle);
                MyRecursiveTask rightTask = new MyRecursiveTask(middle + 1, end);
                leftTask.fork();
                rightTask.fork();
                return leftTask.join() + rightTask.join();
            }
        }
    }
    
    在这个例子中,MyRecursiveTask 将一个求和任务分解为多个小任务,然后并行执行,最终合并结果。

# 3. Fork/Join 框架的工作机制

  • 任务拆分(Fork):每个任务可以递归地拆分为多个子任务,直到任务的粒度足够小。
  • 任务执行:ForkJoinPool 中的每个工作线程都会维护一个双端队列,任务会被添加到队列中,线程从队列中取出任务执行。
  • 工作窃取:当某个工作线程的任务队列为空时,它会从其他工作线程的队列末端窃取任务来执行,从而避免线程闲置,最大化 CPU 的利用率。

# 4. Fork/Join 框架的优缺点

  • 优点:
    • 高效利用多核 CPU:通过将任务拆分为多个子任务并行执行,Fork/Join 框架能够充分利用多核 CPU 的性能。
    • 工作窃取算法:提高了任务的负载均衡性,避免线程闲置。
  • 缺点:
    • 任务拆分的开销:任务拆分和合并的开销较大,如果任务粒度不够细,可能会导致拆分的开销大于并行执行的收益。
    • 复杂性:任务的拆分和合并需要开发者自行控制,代码相对复杂。

# 5. Fork/Join 框架的应用场景

  • 大规模数据处理:适用于需要对大量数据进行并行处理的场景,例如并行计算、矩阵运算等。
  • 递归问题求解:特别适用于那些可以递归分解的问题,例如斐波那契数列的计算、归并排序等。
  • 图像处理:在图像处理领域,可以将图像分割为多个部分并行处理,从而提高处理速度。

# 6. 与其他并发工具的比较

  • 与线程池:Fork/Join 框架和线程池都可以用于并行执行任务,但 Fork/Join 框架更适合于需要将任务递归拆分并行执行的场景,而线程池更适合用于处理独立的、相互无关的任务。
  • 与并行流:Java 8 引入了并行流(Parallel Streams),其底层也是基于 Fork/Join 框架,但并行流封装了任务拆分和执行的过程,使得代码更加简洁易用。相比之下,Fork/Join 框架提供了更细粒度的控制,适用于需要精细控制任务执行的场景。

# 7. 总结

Fork/Join 框架是 Java 并发编程中的一个强大工具,主要用于解决需要将任务拆分为多个子任务并行执行的问题。通过 ForkJoinPool 和 ForkJoinTask,开发者可以实现复杂的分治算法,充分利用多核 CPU 的性能。在实际使用中,应根据任务的性质来决定是否使用 Fork/Join 框架,特别是在需要处理递归任务或大规模数据时,可以显著提升程序的执行效率。理解 Fork/Join 框架的工作机制和应用场景,可以帮助开发者在多线程编程中编写更加高效的代码。

上次更新: 2024/11/01, 13:45:14
ThreadLocal
ScheduledThreadPoolExecutor

← ThreadLocal ScheduledThreadPoolExecutor→

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