文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何理解Java 并发编程中的ForkJoin框架

2023-06-25 16:54

关注

如何理解Java 并发编程中的ForkJoin框架,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

1、什么是ForkJoin框架

ForkJoin框架是java的JUC包里提供的,用于处理一些比较繁重的任务,会将这个大任务分为多个小任务,多个小任务处理完成后会将结果汇总给Result,体现的是一种“分而治之”的思想。第一步,拆分fork任务,将大任务分为多个小任务;第二步,归并join,会将小任务的处理结果进行归并为一个结果。

如何理解Java 并发编程中的ForkJoin框架

2、ForkJoinTask

ForkJoinTask是ForkJoin框架的提供的任务API,ForkJoinTask是一个抽象类,有两个主要的实现类,RecursiveTask和RecursiveAction,其中RecursiveTask和RecursiveAction的主要区别是,RecursiveAction没有返回值,而RecursiveTask是有返回值的

如何理解Java 并发编程中的ForkJoin框架

3、ForkJoinPool

ForkJoinPool类是forkjoin框架的线程池实现,基于ExecutorService接口。这个线程池是jdk1.7才加入的,用于管理线程,执行forkjoin的任务。对于线程池的使用,我们使用ThreadPoolExecutor比较多,可以在idea里看一下uml类图,可以看出ForkJoinPool和ThreadPoolExecutor实现差不多的。

如何理解Java 并发编程中的ForkJoin框架

ForkJoinPool()ForkJoinPool(int parallelism)ForkJoinPool(int parallelism, ForkJoinWorkerThreadFactory factory, UncaughtExceptionHandler handler, boolean asyncMode)

几个重要的参数:

使用时候,可以直接创建ForkJoinPool,可以不传参,不传参的情况,默认指定的线程并行数为Runtime.getRunTime().availableProcessors();,表示根据cpu核数创建可用线程数

ForkJoinPool forkJoinPool = new ForkJoinPool();ArraySortTask task = new ArraySortTask(array , 0 , size);forkJoinPool.submit(task);task.get();

也是可用传参,对并行度进行指定的public ForkJoinPool(int parallelism), parallelism并行度,并行执行几个线程

将forkjoin任务加入到FrokJoinPool线程池有几种方式

4、打印斐波那契数列

ForkJoin框架可以用于一些递归遍历的场景,对于斐波那契数列,你可以比较熟悉,因为在面试中有时候经常问到,斐波那契数列的特点就是最后一项的结果等于前面两项的和

package com.example.concurrent.forkjoin;import java.util.concurrent.ExecutionException;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.ForkJoinTask;import java.util.concurrent.RecursiveTask;public class Fibonacci extends RecursiveTask<Integer>{    private int n;    public Fibonacci(int n) {        this.n = n;    }    @Override    protected Integer compute() {        if (n <= 1)            return n;        Fibonacci f1 = new Fibonacci(n - 1);        f1.fork();        Fibonacci f2 = new Fibonacci(n - 2);        f2.fork();        return f1.join() + f2.join();    }    public static void main(String[] args) throws ExecutionException, InterruptedException {        ForkJoinPool pool = new ForkJoinPool();        for (int i = 0; i< 10; i++) {            ForkJoinTask task = pool.submit(new Fibonacci(i));            System.out.println(task.get());        }    }}

5、ForkJoin归并排序

面试题:快速实现对一个长度百万的数组的排序

难点:可以使用归并排序,多线程如何组织实现归并排序

package com.example.concurrent.forkjoin;import java.util.Arrays;import java.util.Random;import java.util.concurrent.ExecutionException;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.RecursiveAction;public class ArraySortTask extends RecursiveAction{    final long[] array; final int lo, hi;    ArraySortTask(long[] array, int lo, int hi) {        this.array = array; this.lo = lo; this.hi = hi;    }    ArraySortTask(long[] array) { this(array, 0, array.length); }    @Override    protected void compute() {        if (hi - lo < THRESHOLD)            // 少于阀值,使用Arrays.sort 快排            sortSequentially(lo, hi);        else {                        // 取中间值            int mid = (lo + hi) >>> 1;            // 拆分任务            invokeAll(new ArraySortTask(array, lo, mid),                    new ArraySortTask(array, mid, hi));            // 归并结果            merge(lo, mid, hi);        }    }    // implementation details follow:    static final int THRESHOLD = 1000;    void sortSequentially(int lo, int hi) {        Arrays.sort(array, lo, hi);    }    void merge(int lo, int mid, int hi) {        long[] buf = Arrays.copyOfRange(array, lo, mid);        for (int i = 0, j = lo, k = mid; i < buf.length; j++)            array[j] = (k == hi || buf[i] < array[k]) ?                    buf[i++] : array[k++];    }    public static void main(String[] args) throws ExecutionException, InterruptedException {        int size = 10_000;        long[] array = new long[size];        Random random = new Random();        for (int i = 0; i< size; i++) {            array[i] = random.nextInt();        }        ForkJoinPool forkJoinPool = new ForkJoinPool();        ArraySortTask task = new ArraySortTask(array , 0 , size);        forkJoinPool.submit(task);        task.get();        for (long a : array) {            System.out.println(a);        }    }}

关于如何理解Java 并发编程中的ForkJoin框架问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯