广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java 并发编程之ForkJoin框架
  • 337
分享到

Java 并发编程之ForkJoin框架

2024-04-02 19:04:59 337人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录1、什么是ForkJoin框架2、ForkJoinTask3、ForkJoinPool4、打印斐波那契数列5、ForkJoin归并排序总结 1、什么是ForkJoin框架 For

1、什么是ForkJoin框架

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

在这里插入图片描述

2、ForkJoinTask

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

在这里插入图片描述

3、ForkJoinPool

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

在这里插入图片描述


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

几个重要的参数:

  • parallelism:并行度,并行执行线程,可用指定,也可以不指定,不指定的情况,是根据cpu核数创建可用的线程
  • ForkJoinWorkerThreadFactory:创建线程的工厂实现
  • UncaughtExceptionHandler :因为未知异常中断的回调处理
  • asyncMode:是否异步,默认情况是false

使用时候,可以直接创建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线程池有几种方式

  • execute():调用其 fork 方法在多个线程之间拆分工作。
  • invoke():在ForkJoinPool线程池上调用invoke方法
  • submit():返回一个Future对象,Future可以进行监控,任务完成后返回结果

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);
        }
    }
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: Java 并发编程之ForkJoin框架

本文链接: https://www.lsjlt.com/news/158022.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java 并发编程之ForkJoin框架
    目录1、什么是ForkJoin框架2、ForkJoinTask3、ForkJoinPool4、打印斐波那契数列5、ForkJoin归并排序总结 1、什么是ForkJoin框架 For...
    99+
    2022-11-12
  • 如何理解Java 并发编程中的ForkJoin框架
    如何理解Java 并发编程中的ForkJoin框架,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1、什么是ForkJoin框架ForkJoin框架是java的JU...
    99+
    2023-06-25
  • Java并发编程之Fork/Join框架的理解
    一、Fork/Join框架的理解 ForkJoinTask类属于java.util.concurrent 包下; ForkJoinTask类下有2个子类,分别为R...
    99+
    2022-11-12
  • Java并发编程之Fork/Join框架的示例分析
    这篇文章主要介绍了Java并发编程之Fork/Join框架的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、Fork/Join框架的理解ForkJoinTask类属...
    99+
    2023-06-15
  • Java并发编程之threadLocal
    目录1、ThreadLocal介绍2、ThreadLocal使用实例3、ThreadLocal实现原理1、ThreadLocal介绍 多个线程访问同一个共享变量时特别容易出现并发问题...
    99+
    2022-11-12
  • Java并发编程之线程中断
    目录线程中断: void interrupted()方法:中断线程,例如,当线程A运行时,线程B可以调用线程A的interrupted()方法来设置线程的中断标志为true并立即返回...
    99+
    2022-11-12
  • Java并发编程之ThreadLocal详解
    目录一、什么是ThreadLocal?二、ThreadLocal的使用场景三、如何使用ThreadLocal四、数据库连接时的使用五、ThreadLocal工作原理六、小结七、注意点...
    99+
    2022-11-12
  • Java并发编程之浅谈ReentrantLock
    目录一、首先看图二、lock()跟踪源码2.1 非公平锁实现2.1.1 tryAcquire(arg)2.1.2 acquireQueued(addWaiter(Node.EXCLU...
    99+
    2022-11-12
  • 构架Java并发模型框架 (转)
    构架Java并发模型框架 (转)[@more@]架Java并发模型框架 - 框架,网站构架,网络构架 - 技术教程网技术教程网 -- 实用技术参考...
    99+
    2023-06-03
  • Java并发编程之Java内存模型
    目录1、什么是Java的内存模型2、为什么需要Java内存模型3、Java内存模型及操作规范4、Java内存模型规定的原子操作5、Java内存模型同步协议6、Java内存模型的HB法...
    99+
    2022-11-12
  • Java并发编程之线程安全性
    目录1.什么是线程安全性2.原子性2.1 竞争条件2.2 复合操作3.加锁机制3.1 内置锁3.2 重入4.用锁保护状态5.活跃性与性能1.什么是线程安全性 当多个线程访问某个类时,...
    99+
    2022-11-13
  • Java并发编程面试之线程池
    目录什么是线程池线程池好处线程池的执行流程怎么用线程池corePoolSizemaximumPoolSizekeepAliveTimeunitworkQueuethreadFacto...
    99+
    2022-11-12
  • 理解Java多线程之并发编程
    目录1 多线程的使用场景2 多线程的缺点2.1 上下文切换的开销(1)上下文切换的开销(2)如何减少上下文切换2.2 多线程中的数据一致性问题(1)线程中访问外部数据的过程(2)线程...
    99+
    2023-02-02
    Java并发编程 java并发编程实战 java并发编程的艺术
  • Java并发编程之同步容器
    目录简介一、什么是同步容器二、为什么要有同步容器三、同步容器的优缺点四、同步容器的使用场景总结简介 同步容器主要分两类,一种是Vector这样的普通类,一种是通过Collection...
    99+
    2022-11-12
  • Java并发编程之Executors类详解
    一、Executors的理解 Executors类属于java.util.concurrent包; 线程池的创建分为两种方式:ThreadPoolExecutor ...
    99+
    2022-11-12
  • Java并发编程之LockSupport类详解
    目录一、LockSupport类的属性二、LockSupport类的构造函数三、park(Object blocker)方法 和 park()方法分析四、parkNanos(Obje...
    99+
    2022-11-12
  • 详解Java高并发编程之AtomicReference
    目录一、AtomicReference 基本使用1.1、使用 synchronized 保证线程安全性二、了解 AtomicReference2.1、使用 AtomicReferen...
    99+
    2022-11-12
  • Java并发编程之详解ConcurrentHashMap类
    前言 由于Java程序员常用的HashMap的操作方法不是同步的,所以在多线程环境下会导致存取操作数据不一致的问题,Map接口的另一个实现类Hashtable 虽然是线程安全的,但是...
    99+
    2022-11-12
  • Java并发编程之StampedLock锁介绍
    StampedLock: StampedLock是并发包里面JDK8版本新增的一个锁,该锁提供了三种模式的读写控制,当调用获取锁的系列函数时,会返回一个long 型的变量,我们称之为...
    99+
    2022-11-13
  • 并发编程之Java内存模型
    目录一、Java内存模型的基础1.1 并发编程模型的两个关键问题1.2 Java内存模型的抽象结构1.3 从源代码到指令重排序1.4 写缓冲区和内存屏障1.4.1 写缓冲区1.4.2...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作