java多线程进阶Fork/Join任务拆分与合并
Posted 烟锁迷城
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程进阶Fork/Join任务拆分与合并相关的知识,希望对你有一定的参考价值。
目录
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 分支/ 合并框架 工作窃取
Java——多线程高并发系列之Fork/Join框架简单应用