java多线程进阶Fork/Join任务拆分与合并

Posted 烟锁迷城

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程进阶Fork/Join任务拆分与合并相关的知识,希望对你有一定的参考价值。

目录

1、简单介绍

1.1、ForkJoinTask子类

1.2、重要方法

1.3、WorkQueue工作队列

1.4、ForkJoinPool线程池

2、应用场景


1、简单介绍

Fork和Join是任务的拆分与合并,因此它们并非单独的方法,而是要结合任务ForkJoinTask来使用。

ForkJoinTask有很多种实现,接下来简单的介绍几种

1.1、ForkJoinTask子类

RecursiveAction:不带返回值的任务

RecursiveATask:带返回值的任务

CountedCompleter:这是一个特殊的任务,fork让task异步执行,join让task同步执行,等待获取到返回值

1.2、重要方法

fork:创建一个异步执行的子任务

join:等待任务完成后返回结果

invoke:开始执行任务,并获得返回结果

1.3、WorkQueue工作队列

WorkQueue是内部的任务队列,是一个双端队列,后进先出,它属于每一个线程。

为了优化任务的执行效率,它采用了一种叫做工作窃取的算法,简单来说,就是当一个线程消耗光了它的任务之后,就会去其他的线程的队列头部来窃取一个任务来执行,由于是后进先出,所以不会对其他线程造成一个竞争影响。

1.4、ForkJoinPool线程池

ForkJoinTask有自己的线程池ForkJoinPool来进行线程服用,它有三个关键方法

invoke:提交任务并进行阻塞,直到任务完成返回合并结果

execute:异步执行任务,无返回值

submit:异步执行任务,返回task本身,可以通过task.get来获取结果

2、应用场景

public class Text 

    public static void main(String[] args) 
        ForkJoinPool pool = new ForkJoinPool();
        ForkJoinTask<Integer> submit = pool.submit(new CountTask(1, 3));
        try 
            Integer integer = submit.get();
            System.out.println(integer);
         catch (InterruptedException e) 
            e.printStackTrace();
         catch (ExecutionException e) 
            e.printStackTrace();
        
    

    static class CountTask extends RecursiveTask<Integer> 

        private Integer start;
        private Integer end;

        public CountTask(Integer start, Integer end) 
            this.start = start;
            this.end = end;
        

        @Override
        protected Integer compute() 
            System.out.println(start + "," + end);
            if (end - start > 20) 
                return createTask();
             else 
                int a = 0;
                for (int i = start; start <= end; i++) 
                    a = a + i;
                
                return a;
            
        

        private Integer createTask() 
            CountTask one = new CountTask(start, end / 2);
            one.fork();
            CountTask two = new CountTask(end / 2, end);
            two.fork();
            return one.join() + two.join();
        
    

以上是关于java多线程进阶Fork/Join任务拆分与合并的主要内容,如果未能解决你的问题,请参考以下文章

java多线程 -- ForkJoinPool 分支/ 合并框架 工作窃取

多线程-Fork/Join

多线程 fork/join 并行计算

Java——多线程高并发系列之Fork/Join框架简单应用

Java——多线程高并发系列之Fork/Join框架简单应用

Java的Fork/Join任务