java Fork/Join 框架的理解以及简单运用

Fork/Join 是一种并行计算模式,主要用于将任务分解为更小的子任务(Fork),递归地解决这些子任务,然后将结果合并(Join)以获得最终结果。这种模式非常适合于可以并行处理的任务,特别是那些可以分解为多个独立子问题的任务。

### Fork/Join 框架的关键概念:

1. **任务(Task)**:表示可以执行的工作单元。在 Java 中,可以通过实现 `Callable` 接口来创建任务。

2. **工作窃取(Work Stealing)**:这是一种算法,工作线程可以从其他线程的队列中窃取任务来执行,以此来平衡负载和提高资源利用率。

3. **Fork**:将一个复杂的任务分解为两个或多个更小的任务。

4. **Join**:等待一个或多个任务完成,并合并它们的结果。

5. **递归**:Fork/Join 模式通常与递归结合使用,即每个子任务可能进一步分解为更小的子任务。

6. **线程池**:Fork/Join 模式通常与线程池一起使用,以便有效地管理线程资源。

### Java 中的 Fork/Join 框架:

Java 7 引入了 `java.util.concurrent` 包中的 `ForkJoinPool` 类,它是专门为执行 Fork/Join 任务设计的线程池。使用 `ForkJoinPool` 可以简化并行任务的执行和管理。

以下是使用 Java Fork/Join 框架的基本步骤:

1. **创建 ForkJoinPool**:根据需要创建一个 `ForkJoinPool` 实例。

2. **定义任务**:实现 `Callable` 接口或继承 `RecursiveTask` 或 `RecursiveAction` 类来定义任务。`RecursiveTask` 有返回值,而 `RecursiveAction` 没有返回值。

3. **分解任务**:在任务的 `call` 方法中实现任务的分解逻辑。

4. **执行任务**:使用 `ForkJoinPool` 的 `invoke` 或 `execute` 方法来执行任务。

5. **合并结果**:对于 `RecursiveTask`,可以在任务完成后获取结果。

import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;

public class ForkJoinExample extends RecursiveTask<Integer> {
    private int start;
    private int end;
    private static final int THRESHOLD = 10;

    public ForkJoinExample(int start, int end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        int result = 0;
        if (end - start <= THRESHOLD) {
            // 基本情况,直接计算
            for (int i = start; i <= end; i++) {
                result += i;
            }
        } else {
            // 分解任务
            int middle = (start + end) / 2;
            ForkJoinExample subTask1 = new ForkJoinExample(start, middle);
            ForkJoinExample subTask2 = new ForkJoinExample(middle + 1, end);

            // 执行子任务
            subTask1.fork();
            subTask2.fork();

            // 合并结果
            result = subTask1.join() + subTask2.join();
        }
        return result;
    }

    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool();
        ForkJoinExample task = new ForkJoinExample(1, 100);
        pool.invoke(task);

        System.out.println("Result: " + task.join());
    }
}

在这个示例中,我们创建了一个计算 1 到 100 整数之和的任务。任务被分解为更小的子任务,直到达到阈值 `THRESHOLD`,然后递归地计算并合并结果。`ForkJoinPool` 负责调度和执行这些任务。

Fork/Join 模式适用于可以分解为多个子任务的场景,如数值计算、大数据处理等。它通过工作窃取和递归分解提高了并行计算的效率。


利用Fork/Join遍历指定文件夹下的txt文件

package com;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RecursiveAction;

public class FileForkJoin extends RecursiveAction {
    private File file;

    public FileForkJoin(File file) {
        this.file = file;
    }

    @Override
    protected void compute() {
        List<FileForkJoin> fileForkJoins= new ArrayList<>();

        if(file.exists()){
            if (file.isDirectory()){
                File[] files = file.listFiles();
                if(files != null){
                    for (File file1 : files) {
                        fileForkJoins.add(new FileForkJoin(file1));
                    }
                }
            }else if(file.isFile() && file.getName().endsWith(".txt")){
                System.out.println(file.getAbsolutePath());
            }
        }
        if(!fileForkJoins.isEmpty()){
            //invokeAll 方法是 ForkJoinTask 的一个静态方法,它允许你启动一组 ForkJoinTask 任务并等待它们全部完成,然后返回包含所有结果的数组。
            for (FileForkJoin fileForkJoin : invokeAll(fileForkJoins)) {
                fileForkJoin.join();
            }
        }

    }

}

public class TestFileForkJoin {
    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool();
        FileForkJoin fileForkJoin = new FileForkJoin(new File("F://"));
        //异步任务
        pool.submit(fileForkJoin);

        fileForkJoin.join();

        System.out.println("end");
    }
}


 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值