并发编程09--ForkJoin

ForkJoin框架其实是线程池ExecutorService的实现,将一个任务分解成多个部分同时运行,最后在将多个结果合并,实现方式类似于分治算法,或者MapRdeuce的思想,利用所有可用的处理能力来提高程序的响应和性能

类结构

ForkJoin框架的核心是ForkJoinPool类,基于AbstractExecutorService扩展。ForkJoinPool中维护了一个队列数组WorkQueue,每个WorkQueue维护一个ForkJoinTask数组和当前工作线程。ForkJoinPool实现了工作窃取(work-stealing)算法并执行ForkJoinTask。
并发编程09--ForkJoin_第1张图片

ForkJoinTask是能够在ForkJoinPool中执行的任务抽象类,父类是Future,具体实现类有很多,这里主要关注RecursiveAction和RecursiveTask以及CountedCompleter。RecursiveAction是没有返回结果的任务,RecursiveTask是需要返回结果的任务,CountedCompleter 在任务完成执行后会触发执行一个自定义的钩子函数。

创建实例只需要实现其compute()方法,在compute()中做最小任务控制,任务分解(fork)和结果合并(join)。
并发编程09--ForkJoin_第2张图片

ForkJoinPool中执行的默认线程是ForkJoinWorkerThread,由默认工厂产生,可以自己重写要实现的工作线程。同时会将ForkJoinPool引用放在每个工作线程中,供工作窃取时使用。

结构如下:

并发编程09--ForkJoin_第3张图片

代码实例:

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import org.apache.commons.lang3.RandomUtils;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * 一个数组内有10万个30左右的数值(非零),要求计算这些值的乘积。
 * 时间要求:2s
 * 堆内存大小:4m
 * 

* 实现方案:通过ForkJoin实现。 */ public class ForkJoinMultiply extends RecursiveTask { private int[] numbers; private static final int THREASHOLD = 10000; private static final int MAX_SIZE = 100000; public ForkJoinMultiply(int[] numbers) { this.numbers = numbers; } @Override protected BigInteger compute() { if(numbers.length<=THREASHOLD){//如果数组容量小于阈值,直接计算乘积。 BigInteger result = BigInteger.ONE; for(int i = 0;i

参考:

https://blog.csdn.net/codingtu/article/details/88729498

你可能感兴趣的:(java)