首页 > 其他分享 >ForkJoinPool

ForkJoinPool

时间:2024-09-20 16:12:22浏览次数:1  
标签:end int ForkJoinPool start 任务 线程

总结

  一个特殊线程池,它专门用于执行 ForkJoinTask

  设计目的是为了更有效地处理 可以被分解成更小任务 的工作负载,这些任务可以通过递归地分叉(fork)和合并(join)来并行执行。

  这种模式非常适合于分治算法,比如快速排序、矩阵乘法等。

特性

  • 工作窃取:ForkJoinPool 使用了一种称为“工作窃取”的算法,其中 空闲的线程 可以 从其他忙于处理任务的线程 那里“窃取”待处理的任务。这有助于保持所有线程忙碌,从而提高整体效率。
  • 轻量级子任务:ForkJoinTask 通常代表一个轻量级的子任务,这样可以减少任务切换的开销。
  • 动态调整:ForkJoinPool 可以根据需要动态调整其大小,但通常建议使用默认设置或显式指定大小。

创建 ForkJoinPool

  • 默认构造函数会创建一个与系统可用处理器数量相匹配的线程数的池。
  • 也可以通过传递自定义参数来创建 ForkJoinPool,例如指定线程数、异常处理器等。

ForkJoinTask

ForkJoinTaskForkJoinPool 中执行任务的抽象类,有两个主要的实现:

  • RecursiveAction:用于 没有返回结果 的任务。
  • RecursiveTask<V>:用于 有返回结果 的任务,这里的 V 表示返回值类型。

示例

public class SumCalculator extends RecursiveTask<Long> {
    private final long[] numbers;
    private final int start;
    private final int end;
    private static final int THRESHOLD = 1000; // 阈值,决定何时停止拆分子任务

    public SumCalculator(long[] numbers, int start, int end) {
        this.numbers = numbers;
        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 += numbers[i];
            }
            return sum;
        } else {
            // 否则将任务拆分成两个更小的任务
            int middle = (start + end) / 2;
            SumCalculator leftTask = new SumCalculator(numbers, start, middle);
            SumCalculator rightTask = new SumCalculator(numbers, middle, end);

            // 异步执行左边的任务
            leftTask.fork();
            // 计算右边的任务
            long rightResult = rightTask.compute();
            // 获取左边任务的结果
            long leftResult = leftTask.join();

            // 返回左右两边任务的结果之和
            return leftResult + rightResult;
        }
    }

    public static void main(String[] args) {
        long[] numbers = new long[100000000];
        for (int i = 0; i < numbers.length; i++) {
            numbers[i] = i;
        }

        ForkJoinPool pool = new ForkJoinPool();
        SumCalculator task = new SumCalculator(numbers, 0, numbers.length);
        long start = System.currentTimeMillis();
        long result = pool.invoke(task); // 提交任务并等待完成

        System.out.println("The sum is: " + result  + "  cost:" + (System.currentTimeMillis() - start));


        long start1 = System.currentTimeMillis();
        long sum = 0;
        for (int i = 0; i < numbers.length; i++) {
            sum += numbers[i];
        }
        System.out.println("sum: " + sum + "  cost: " + (System.currentTimeMillis() - start1));
    }
}

  

标签:end,int,ForkJoinPool,start,任务,线程
From: https://www.cnblogs.com/anpeiyong/p/18422716

相关文章

  • ThreadPoolExecutor 与 ForkJoinPool比较
    都是Java并发包java.util.concurrent中用于执行任务的线程池,但它们的设计目的和适用场景有所不同。下面是两者之间的主要区别:设计目标ThreadPoolExecutor:主要用于处理大量异步任务。适用于各种类型的任务,特别是那些独立运行且不需要相互协作的任务。提供了高度的......
  • 实战:ForkJoinPool对大文件导入技术优化指南
    1、ForkJoinPool简介Fork/Join框架是Java7提供了的一个用于并行执行任务的框架。ForkJoinPool是Java中提供了一个线程池,特点是用来执行分治任务。主题思想是将大任务分解为小任务,然后继续将小任务分解,直至能够直接解决为止,然后再依次将任务的结果合并。ForkJoinPool是一种工......
  • Java线程池ForkJoinPool原理分析
    目录1.由一道算法题引发的思考2.基于归并排序算法实现2.1什么是归并排序2.2归并排序动图演示2.3使用归并排序实现上面的算法题单线程实现归并排序Fork/Join并行归并排序2.4并行实现归并排序的优化和注意事项3.Fork/Join框架介绍3.1什么是Fork/Join3.2应用......
  • 记录一次代码中的ForkJoinPool.getCommonPoolParallelism()
    @Configuration@Slf4jpublicclassThreadPoolConfig{privatestaticfinalintCORE_POOL_SIZE=6;privatestaticfinalintMAX_POOL_SIZE=12;privatestaticfinalintKEEP_ALIVE_TIME=60;privatestaticfinalintQUEUE_CAPACITY=......
  • JAVA使用ForkJoinPool实现子任务拆分进行数值累加代码示例
      SumTask.javaimportjava.util.concurrent.RecursiveTask;/***定义任务和拆分逻辑*RecursiveTask<Long>这个是有返回值的*如果不需要返回值可以用RecursiveAction*/publicclassSumTaskextendsRecursiveTask<Long>{/***累加的开始值......
  • ForkJoinPool在生产环境中使用遇到的一个问题
    1、背景在我们的项目中有这么一个场景,需要消费kafka中的消息,并生成对应的工单数据。早些时候程序运行的好好的,但是有一天,我们升级了容器的配置,结果导致部分消息无法消费。而消费者的代码是使用CompletableFuture.runAsync(()->{while(true){.....}})来实现的。即:需要消......
  • 【揭秘】ForkJoinPool全面解析
    文章摘要ForkJoinPool是Java中的并行计算框架,其优点在于能够高效利用多核处理器资源,它采用分治策略将大任务拆分成小任务,通过工作窃取算法平衡负载,从而实现任务的并行执行和快速完成,此外,ForkJoinPool还提供了简洁的API和丰富的任务控制机制,支撑开发人员开发高效的并行代码。核心......
  • ForkJoinPool实践
    最近在看一本15年出版的《Java并发编程的艺术》一书,其中看到并发编程时间部分的ForkJoinPool功能时,突然发现这个功能实际使用上就是把一个大任务分成多个小的子任务,然后使用多个线程完成。这个场景跟我之前写过的自定义Java自定义异步功能实践有点异曲同工之妙,只不过这里有有个子......
  • 多线程 ForkJoinPool
    ava7提供了ForkJoinPool来支持将一个任务拆分成多个“小任务”并行计算,再把多个“小任务”的结果合并成总的计算结果。ForkJoinPool是ExecutorService的实现类,因此是一种......
  • ForkJoinPool实践
    最近在看一本15年出版的《Java并发编程的艺术》一书,其中看到并发编程时间部分的ForkJoinPool功能时,突然发现这个功能实际使用上就是把一个大任务分成多个小的子任务,然后使用......