什么是ForkJoin:ForkJoin是jdk1.7后出现的,用于大数据量处理时,并行执行任务,提高效率(把大任务拆分为小任务),一个线程并发成多个
ForkJoin特点:
工作窃取:A B两个线程同时执行任务,A执行一半,B执行完了,B就会将A的任务拿过来执行,提高效率;实现这一效果的基础是,它们维护的是双端队列,两端都可以去任务。
ForkJoin的使用
测试:
/*
求和计算
*/
public class ForkJoinDemo extends RecursiveTask<Long> {
private Long start;
private Long end;
//临界值
private Long temp = 10000L;
public ForkJoinDemo(Long start, Long end) {
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
if ((end-start)<temp){
Long sum = 0L;
for (int i = start; i <= end; i++) {
sum += i;
}
return sum;
}else {//ForkJoin递归
Long middle = (start+end)/2; //取中间值
ForkJoinDemo task1 = new ForkJoinDemo(start, middle);
task1.fork();//拆分任务,把任务压入线程队列
ForkJoinDemo task2 = new ForkJoinDemo(middle+1, end);
task2.fork();//拆分任务,把任务压入线程队列
return task1.join() + task2.join();
}
}
}
三种测试计算结果
public class TestResult {
public static void main(String[] args) throws ExecutionException, InterruptedException {
test01();//sum=500000000500000000 时间:18698
test02();//sum=500000000500000000 时间:12997
test03();//sum=500000000500000000 时间:457
}
//普通方法
public static void test01(){
Long sum = 0L;
long start = System.currentTimeMillis();
for (int i = 0; i <= 10_0000_0000; i++) {
sum +=i;
}
long end = System.currentTimeMillis();
System.out.println("sum="+sum+"时间:"+(end-start));
}
//ForkJoin方法
public static void test02() throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinDemo(0L, 10_0000_0000L);
ForkJoinTask<Long> submit = forkJoinPool.submit(task);//提交任务
Long sum = submit.get();//获取返回值结果
long end = System.currentTimeMillis();
System.out.println("sum="+sum+"时间:"+(end-start));
}
//Stream并行流
public static void test03(){
long start = System.currentTimeMillis();
long sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0, Long::sum);
long end = System.currentTimeMillis();
System.out.println("sum="+sum+"时间:"+(end-start));
}
}