精华内容
下载资源
问答
  • 2022-06-04 15:28:11

    在Verilog中我们对线程(即独立运行的程序,分为父线程和子线程)的使用有:

    1、begin--end块 (顺序执行)

    2、fork----join块 (并行执行)

    而在SV中又增加了两种新的创建线程的方法:

    1、fork join_any:只要有一个子线程优先完成就跳出fork join_any块,执行父线程。

    2、fork join_none:直接跳出fork join_none块,执行父线程。

    介于大家都对此有一定了解程度,那我就直接说重点:

    1、fork join_any和fork join_none影响的都是父线程的执行。

    2、delay的优先级最高,所有顺序都是按照时序执行。只有当delay相同时才会显现出fork join_any和fork join_none的区别,才会遵守上文所说规则。

    有写不对的地方希望大家批评指正!

    更多相关内容
  • 什么是ForkJoinForkJoin分支合并、ForkJoin工作窃取、ForkJoin大数据求和计算什么是ForkJoinForkJoin:分支合并ForkJoin特点:工作窃取如何让使用ForkJoinForkJoin求和计算Demo 什么是ForkJoinForkJoin(分支...

    什么是ForkJoin、ForkJoin分支合并、ForkJoin工作窃取、ForkJoin大数据求和计算

    什么是ForkJoin?

    ForkJoin(分支合并)是jdk1.7之后出来的,并行执行任务,提高效率,用在大数据量场景下。

    大数据:Map Reduce(把大任务拆分成多个小任务,怎么拆分用到了二分算法),每个小任务得出自己的结果,之后再把结果汇总,汇总的过程就是分支合并的思想。

    ForkJoin:分支合并

    ForkJoin会把一个大任务分成若干个小任务去执行(任务是双端队列去存储的,两端都可以操作),然后再合并结果集。
    请添加图片描述

    ForkJoin特点:工作窃取

    ForkJoin会把一个大任务分成若干个小任务去执行(任务是双端队列去存储的,两端都可以操作),然后再合并结果集。
    线程的执行速度不一样,因此先执行完的线程,为了避免浪费时间,会去还没有执行完的线程那里拿到它未执行完的任务,去帮它执行,之所以能拿到,也是因为任务是双端队列存储的,两头都可以操作。

    ForkJoinPool主要是为了并行计算使用(也就是新增加的并行流),但我觉得更适合IO密集型的场景。
    比如大规模的并行查询。而CPU密集型的操作,过多的线程切换可能会影响效率
    请添加图片描述

    如何让使用ForkJoin

    • 1.ForkJoinPool,通过ForkJoinPool来执行
    • 2.计算任务forkJoinPool.execute(ForkJoinTask task)
    • 3.计算类要继承ForkJoinTask(执行任务RecursiveTask:有返回值 RecursiveAction:无返回值)

    Class ForkJoinPool有一个异步执行任务的方法

    在这里插入图片描述

    在这里插入图片描述

    我们需要用到有返回值的RecursiveTask

    使用RecursiveTask需要继承RecursiveTask,并定义返回值类型

    class Fibonacci extends RecursiveTask<Integer>
    

    ForkJoin求和计算Demo

    import java.util.concurrent.*;
    import java.util.stream.LongStream;
    
    /**
     * 求和计算
     * 1.最low的:循环求和
     * 2.一般的:ForkJoin分支求和
     * 3.最快的:Stream并行流求和
     */
    public class ForkJoinDemo {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            new ForkJoinDemo().test1();
            new ForkJoinDemo().test2();
            new ForkJoinDemo().test3();
            /**
             * test1===>和为500000000500000000,耗时9937
             * test2===>和为500000000500000000,耗时8622
             * test3===>和为500000000500000000,耗时276
             */
    
    
        }
    
        //1.最low的:循环求和
        public void test1() {
            long start = System.currentTimeMillis();
            Long sum = 0L;
            for (Long i = 0L; i <= 10_0000_0000L; i++) {
                sum += i;
            }
            long end = System.currentTimeMillis();
            System.out.println("test1===>和为" + sum + ",耗时" + (end - start));
        }
    
        //2.一般的:ForkJoin分支求和
        public void test2() throws ExecutionException, InterruptedException {
            long start = System.currentTimeMillis();
            // 也可以使用公用的线程池 ForkJoinPool.commonPool():
            // pool = ForkJoinPool.commonPool()
            ForkJoinPool pool = new ForkJoinPool();
            ForkJoinTask<Long> task = pool.submit(new MySumForkJoin(0L, 10_0000_0000L));//提交任务
            Long sum = task.get();
            long end = System.currentTimeMillis();
            System.out.println("test2===>和为" + sum + ",耗时" + (end - start));
        }
    
        //3.最快的:Stream并行流求和
        public void test3() {//没有Long的拆箱装箱操作
            long start = System.currentTimeMillis();
            long sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0, Long::sum);//reduce第一个参数为0,为了保证,在进行流条件计算下,保证每次累计的值不受多线程影响
            long end = System.currentTimeMillis();
            System.out.println("test3===>和为" + sum + ",耗时" + (end - start));
        }
    }
    
    
    /**
     * 如何让使用ForkJoin
     * 1.ForkJoinPool,通过ForkJoinPool来执行
     * 2.计算任务forkJoinPool.execute(ForkJoinTask task)
     * 3.计算类要继承ForkJoinTask(执行任务RecursiveTask:有返回值  RecursiveAction:无返回值)
     */
    class MySumForkJoin extends RecursiveTask<Long> {
        private Long start;//开始值
        private Long end;//结束值
        private Long criticalValue = 10000L;//临界值,超过这个值开始分任务执行
    
        public MySumForkJoin(Long start, Long end) {
            this.start = start;
            this.end = end;
        }
    
        //计算方法:递归调用的
        @Override
        protected Long compute() {
            if (end - start <= criticalValue) {
                Long sum = 0L;
                for (Long i = start; i <= end; i++) {
                    sum += i;
                }
                return sum;
            } else {//ForkJoin执行分支合并计算,
    //            System.out.println("开始ForkJoin执行分支合并计算");
                //1.先求中间值
                Long middle = (start + end) / 2;//不直接(start+end)/2,防止溢出
                /*把任务一分为二,递归拆分(注意此处有递归)到底拆分成多少分 需要根据具体情况而定*/
                MySumForkJoin task1 = new MySumForkJoin(start, middle);
                MySumForkJoin task2 = new MySumForkJoin(middle + 1, end);
    //            task1.fork();//拆分任务,把任务压入双端队列,这里手动只拆分成两个任务,可以拆分多个
    //            task2.fork();//拆分任务,把任务压入双端队列
                invokeAll(task1, task2);//拆分任务,把任务压入双端队列
    
                /**
                 * compute分出多个task后:以task1,task2为例
                 * 错误做法:
                 * 1)依次执行task1.fork(),task2.fork()
                 * 2)依次执行task1.join(),task2.join()
                 * 正确做法:
                 * 1)直接调用invokeAll(task1,task2)
                 *
                 * fork():
                 * 把task置入当前ForkJoinWorkerThread的queue中,等待被消费
                 * join():
                 * 当前ForkJoinWorkerThread执行等待该task执行结束
                 *
                 * 错误做法过程:
                 * 将task1与task2置入queue中,当前ForkJoinWorkerThread停下来等待task1,task2的执行结束。
                 *
                 * 分析:
                 * 当前的ForkJoinWorkerThread可以说join之后什么事情都没有做,只是等待ing。而task1和task2会在新的线程中执行。
                 * 会浪费当前ForkJoinWorkerThread的宝贵线程资源。而且最糟糕的是,会创建一个新的ForkJoinWorkerThread去执行新的task,可想而知,如果任务量特别多,那会同时开启特别多的线程。
                 */
                return task1.join() + task2.join();
            }
        }
    }
    
    展开全文
  • 主要介绍了Java ForkJoin框架的原理及用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 主要介绍了java8中forkjoin和optional框架使用心得以及用法讲解,需要的朋友参考下吧。
  • 主要介绍了java中的fork join框架的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 从自己管理Java线程,到各种更好几的解决方法,Executor服务、ForkJoin 框架以及计算中的Actor模型。  Java并发编程的4种风格:Threads,Executors,ForkJoin和Actors  我们生活在一个事情并行发生的世界。自然...
  • java Fork Join框架及使用,java自带的多线程框架,来处理多线程的问题
  • Fork join 直到所有线程运行完毕,程序才会进入下一个阶段执行后续代码。 Fork join_any 块中任意一个线程运行结束,就可以进入下一个阶段。 Fork join_none 块中线程与下一阶段并行,无需等待。 示例 ...

    Fork join

    直到所有线程运行完毕,程序才会进入下一个阶段执行后续代码。

    Fork join_any

    块中任意一个线程运行结束,就可以进入下一个阶段。

    Fork join_none

    块中线程与下一阶段并行,无需等待。

    示例

    Fork join

    等到statement1、statement2、statement3全部执行完之后,才会执行statement4。

    Fork join_any

    等到statement1、statement2、statement3中任意一个执行完之后,就会执行statement4。

    Fork join_none

    statement4与其他statement同时执行,无需依赖其他线程进度。

    展开全文
  • ForkJoin的使用

    千次阅读 2022-04-12 14:06:19
    目录前言 ...ForkJoin是JDK1.7加入的多线程并行处理框架。ForkJoin使用`分而治之`的思想,把一个大任务拆分成一个个小任务,然后再聚合,得到最终结果。这有点像Hadoop中的MapReduce。还支持工作窃取。

    前言

    • ForkJoin是JDK1.7加入的多线程并行处理框架。ForkJoin使用分而治之的思想,把一个大任务拆分成一个个小任务,然后再聚合,得到最终结果。这有点像Hadoop中的MapReduce。还支持工作窃取。
    • 下面附上ForkJoin Java并发动画。

    这个Jar包下载地址: https://sourceforge.net/projects/javaconcurrenta/files/,还有很多有意思的动画,帮助我们学习JUC。

    在这里插入图片描述

    什么是工作窃取:假设有A、B两个线程执行一个任务,A比较快,把活儿干完了,这时候A可以把B的一部分活接过来。这样总体来说会加快任务执行速度。

    应用

    需求

    • 假设有这样一个需求:我要统计用户表里全部的金额。这个表里有17000003条数据。如果我直接用SQL统计很慢,如下图所示。
      在这里插入图片描述
    • 花费了4.563秒才查出来。
    • 我发现每次1000000条还是很快的,如下图所示。
      在这里插入图片描述
    • 我就想是否可以写个程序,拆分成多个小任务,分批查询,然后合并结果。

    使用

    根据id范围查询求SUM

    ...省略...
     @Override
        public long sumRecord(int toId, int fromId) {
            QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
            // 用in语句合并成一条SQL,避免多次请求数据库的IO
            queryWrapper.ge("id", fromId);
            queryWrapper.le("id", toId);
            queryWrapper.select("IFNULL(SUM(money),0) as money");
            List<Users> users = usersMapper.selectList(queryWrapper);
            if (!CollectionUtils.isEmpty(users)) {
                return users.get(0).getMoney();
            }
            return 0;
        }
    ...省略...
    
    

    创建任务类和测试用例

     ...省略...
    
        @Test
        public void sumTask() {
            long startTime = System.currentTimeMillis();
            ForkJoinPool pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() * 2);
            // 模拟千万数据
            int min = 1;
            int max = 17000003;
            SumTask sumTask = new SumTask(min, max, userService);
            pool.invoke(sumTask);
    
            System.out.println("总数 " + sumTask.join() +
                    " 执行时间 " + (System.currentTimeMillis() - startTime));
    
        }
    
        public static final Integer THRESHOLD = 1000000;
    
        public static class SumTask extends RecursiveTask<Long> {
    
            int fromId;
            int toId;
            private UserService userService;
    
    
            public SumTask(int fromId, int toId, UserService userService) {
                this.fromId = fromId;
                this.toId = toId;
                this.userService = userService;
            }
    
            @Override
            protected Long compute() {
                if (toId - fromId < THRESHOLD) {
                    return sumRecord(toId, fromId);
                } else {
                    int mid = (fromId + toId) / 2;
                    SumTask left = new SumTask(fromId, mid, userService);
                    SumTask right = new SumTask(mid + 1, toId, userService);
                    invokeAll(left, right);
                    return left.join() + right.join();
                }
            }
    
            public Long sumRecord(int toId, int fromId) {
                System.out.println(" 参数 " + fromId + " " + toId);
                return userService.sumRecord(toId, fromId);
            }
    
    
        }
    ...省略...
    

    执行结果

    • 执行结果明显速度快了。
      在这里插入图片描述

    小结

    • 我们可以在new ForkJoinPool(int parallelism)传入线程数(默认是CPU核心数),进行调优。
    • 如果是继承RecursiveAction:用于没有返回结果的任务。

    完整代码

    展开全文
  • ForkJoin

    2018-10-24 20:37:32
    最近用到了forkJoin, 可以拆分任务/汇总结果。具体原理可以参考其他文档。疑惑的是new ForkJoinPool(4)不能提供队列大小设置,只有设置一个核心线程数。也就是说默认使用无界队列。这里采用的是workQueue的双向链表...
  • forkjoin rxjsIf you are confused about the differences between forkJoin, zip, combineLatest and withLatestFrom, you are not alone! :) 如果您对forkJoin , zip , combineLatest和withLatestFrom之间的...
  • ForkJoin 线程池

    2022-01-18 09:55:40
    ForkJoin 线程池是 jdk7 之后引入的一个并行执行任务的框架,其核心思想也是将任务分割为子任务,有可能子任务还是很大,还需要进一步拆解,最终得到足够小的任务。将分割出来的子任务放入双端队列中,然后几个启动...
  • fork join

    2019-10-30 11:07:08
    initial begin ........ ...之间的语句都是顺序执行,特别中间有延迟时间时,就是顺序累加的结果。...fork ..... join 之间的语句都是并行执行的,特别是延迟时间也是并行的,不是相互累加的结果。 ...
  • 在JDK1.7中引入了一种新的Fork/Join线程池,它可以将一个大的任务拆分成多个小的任务并行执行并汇总执行结果。 Fork/Join采用的是分而治之的基本思想,分而治之就是将一个复杂的任务,按照规定的阈值划分成多个简单...
  • 文章目录线程池任务类型和ForkJoin实战详解线程池任务类型分治算法Fork/Join框架介绍Fork/Join使用Fork/Join实战案例RecursiveAction类型RecursiveTask类型CountedCompleterForkJoin原理分析ForkJoin流程图 ...
  • Java并发编程——ForkJoin详解

    千次阅读 2021-11-13 19:26:12
    Fork/Join 框架是 Java7 提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。类似于Java 8中的parallel Stream。 【只能将任务1个切分为两个...
  • SV 中 fork join 的用法

    2022-05-28 10:35:14
    fork join 的三种用法: 1、fork join 2、fork join_any 3、fork join_none wait fork disable fork 一道fork join的经典面试题: fork join用来提起并行的线程,只能用于仿真验证,不可综合。 fork join 的...
  • Fork Join是Java7提供的并行执行任务的框架,是一个把大任务分割成若干小任务,小任务可以继续不断拆分n多个小任务,最终汇总小任务的结果得到大任务结果的框架。
  • ForkJoin小实例

    2021-12-08 17:58:48
    话不多少直接上代码,数据密度越大,这种多线程的速度越明显。 package main.hello; import java.util.Random;... * @ClassName ForkJoin * @Description //TODO * @Author bzx * @Date 2021/12/8 16:18 *
  • forkjoin结构中,父进程会被阻塞直到所有的子进程结束; fork...join_any结构中,父进程会被阻塞直到其中任意一个子进程结束; fork....join_none父进程会立即与产生的所有进程并发执行。 fork中每条语句并行...
  • 本文参考绿皮书第七章,线程及其线程间的通信,Verilog HDL A ...System Verilog线程——fork join的理解使用概述顺序块与并发块(Sequential and Parallel Blocks)begin...end块fork...joinfork...join_any与for.
  • 并发编程之Future&ForkJoin框架原理分析
  • ForkJoin调用接口

    2021-10-13 18:06:36
    Map,InfoVO> infoVOMap = forkJoinTask.join(); /** * 多任务查询 */ public class PriceTask extends RecursiveTask,InfoVO>> { /** * sku集合 */ private Set<Long> skuIds; /** * */ private InfoSoaService ...
  • jbpm4.3 修复 fork join bug

    2019-03-22 01:51:01
    NULL 博文链接:https://sunlujing.iteye.com/blog/914429
  • combineLatest在需要订阅多个数据流的最新数据时使用。forkJoin在需要等多个接口返回数据后才能进行下一步操作时使用。combineLatest和forkJoin的区别...
  • 任务量大,数据量大,使用多线程forkjoin,加快速度,提高效率,比如一百万个数求和 forkjoin可分为两个部分,fork 把发任务分成小任务,一个子线程负责一个小任务,join合并线程执行结果,整个过程使用递归实现,...
  • package forkjoin; import java.util.concurrent.*; import java.util.stream.LongStream; public class TestForkJoin { public static void main(String[] args) throws ExecutionException, ...
  • java 中的fork join框架

    2022-04-29 17:19:38
    java 中的fork join框架 fork join框架是java 7中引入框架,这个框架的引入主要是为了提升并行计算的能力。 fork join主要有两个步骤,第一就是fork,将一个大任务分成很多个小任务,第二就是join,将第一个任务的...
  • 1. ForkJoin简介2. ForkJoin的使用使用步骤代码示例3. 三种方式的效率比较(1) 普通方式(For循环)(2) ForkJoin(3) Stream并行流 1. ForkJoin简介 ForkJoin的作用是将一个任务划分成多个小任务,让多个线程去并行...
  • ForkJoin框架源码分析(详细)

    千次阅读 2020-06-30 15:55:02
    ForkJoin框架是CompletableFuture和java8 stream,ConsurrentHashMap等并发包中使用到的框架。主要用于分片处理的场景。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 45,135
精华内容 18,054
关键字:

forkjoin