Fork就是把大任务切分为若干子任务并行执行,Join就是合并这些子任务的执行结果,最后得到这个大任务的结果。
要使用ForkJoin框架,必须首先创建ForkJoin任务。它提供在任务中执行fork()和join()操作的机制。
Fork/Join框架提供了以下两个子类:
1:RecursiveAction:用于没有返回结果的任务
2:RecursiveTask:用于有返回结果的任务
ForkJoinPool:ForkJoinTask需要通过ForkJoinPool来执行
ForkJoinPool由ForkJoinTask数组和ForkJoinWorkerThread数组组成,ForkJoinTask数组负责将存放程序提交给ForkJoinPool的任务,而ForkJoinWorkerThread数组负责执行这些任务。
计算 1+2+3+4+......+100的结果示例:
1 class CountTask extends RecursiveTask<Integer>{//因为是有返回,所以继承RecursiveTask 2 private static final int THRESHOLD = 10;//阈值 3 private int start; 4 private int end; 5 public CountTask(int start, int end){ 6 this.start = start; 7 this.end = end; 8 } 9 @Override 10 protected Integer compute(){ 11 int sum = 0; 12 //如果任务足够小就计算任务 13 boolean canCompute = (end - start) <= THRESHOLD; 14 if (canCompute){ 15 for (int i = start; i <= end; i++){ 16 sum += i; 17 } 18 }else { 19 //如果任务大于阈值,就分裂成两个子任务计算 20 int middle = (start + end) / 2; 21 CountTask leftTask = new CountTask(start, middle); 22 CountTask rightTask = new CountTask(middle + 1, end); 23 //执行子任务 24 leftTask.fork(); 25 rightTask.fork(); 26 //等待子任务执行完,并得到计算结果 27 int leftResult = leftTask.join(); 28 int rightResult = rightTask.join(); 29 //合并子任务 30 sum = leftResult + rightResult; 31 } 32 return sum; 33 } 34 public static void main(String[] args){ 35 ForkJoinPool forkJoinPool = new ForkJoinPool(); 36 //生成一个计算任务,负责计算1+2+3+4 37 CountTask task = new CountTask(1, 100); 38 //执行子任务 39 Future<Integer> result = forkJoinPool.submit(task); 40 try { 41 System.out.println(result.get()); 42 }catch (InterruptedException e){ 43 }catch (ExecutionException e){ 44 } 45 } 46 }
ForkJoinTask与一般任务的主要区别在于它实现compute方法。