任务拆分独立计算笼统的来讲就是一个大任务被分成若干个小任务,并行计算之后再将结果合并的过程。主要有MapReduce、ForkJoin等。
MapReduce与ForkJoin的相似点:1.他们都是用于执行并行任务的;2.他们的基本思想都是把问题分解为一个个彼此独立的或可分解的子问题分别进行计算,再合并结果。
MapReduce与ForkJoin的不同点:1.MapReduce的任务可以针对集群内的所有计算节点,可以充分利用集群的能力完成计算任务,ForkJoin更加类似于单机版的MapReduce;2.MapReduce是把大数据集切分成小数据集,并行分布计算后再合并,ForkJoin是将一个问题递归分解成子问题再将子问题并行运算后合并结果;3.ForkJoin只有在必要时如任务非常大的情况下才分割成一个个小任务,而MapReduce总是在开始执行第一步进行分割;4.ForkJoin更适合一个JVM内线程级别,而MapReduce适合分布式环境系统。
这篇博客主要从代码层面讲解如何使用ForkJoin进行简单的任务拆分独立计算。以计数求和为例,废话不多说,直接上代码~
一、代码
package com.xzw.forkjoin;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
public class CountTask extends RecursiveTask<Integer>{
public static final int threshold = 5;
private int start;
private int end;
public CountTask(int start, int end){
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
int sum = 0;
//如果任务足够小就计算任务
boolean canCompute = (end - start) <= threshold;
if (canCompute) {
System.out.println(Thread.currentThread().getName() + " start:" + start + " end:" + end);
for (int i = start; i <= end; i++) {
sum += i;
}
}else {
//如果任务大于阈值,就分裂成两个子任务进行计算
int middle = (start + end) / 2;
CountTask leftTask = new CountTask(start, middle);
CountTask rightTask = new CountTask(middle + 1, end);
leftTask.fork();
rightTask.fork();
//等待任务执行结束合并其结果
sum = leftTask.join() + rightTask.join();
}
return sum;
}
public static void main(String[] args) {
ForkJoinPool forkJoinPool = new ForkJoinPool();
CountTask task = new CountTask(1, 200);
Future<Integer> resultFuture = forkJoinPool.submit(task);
try {
System.out.println(resultFuture.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
二、结果截图
至此,一个简单的任务拆分独立计算就完成了。
你们在此过程中还遇到了什么问题,欢迎留言,让我看看你们都遇到了哪些问题。