之前的一个小挫让我意识到自己的很多不足之处,所以决定深入了解一下java并发相关知识。
Fork/Join是jdk1.7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最后汇总每个小任务结果后得到大任务的框架。
Fork/Join相关类说明
ForkJoinTask:如果要使用Fork/join框架必须先创建一个ForkJoin任务,他提供了fork()和join()方法,fork()方法用于在一个已经存在的任务中,启动一个拆分后的任务。join()方法用允许一个ForkJoinTask等待另一个ForkJoinTask执行完成。但是一般情况下我们不需要直接使用ForkJoinTask类,而是使用ForkJoinTask的两个子类。
RecursiveTask:用于有返回结果的任务
RecursiveAction:用于没有返回结果的任务
ForkJoinPool:用于执行ForkJoinTask类。
下面通过一个计算1到100的和例子来说明一下Fork/Join的用法,例子虽然不太贴切,但相信足以让你明白Fork/Join的使用方法。
package com.scy.thread;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
public class CountTask extends RecursiveTask<Integer>{
private static final long serialVersionUID = 5550891835302602757L;
private int start;
private int end;
private final int THREADCOUNT=50;
/**
* 构造方法
* @param start 起始值
* @param end 结束值
*/
public CountTask(int start, int end){
this.start = start;
this.end = end;
}
/**
* @param args
* @throws ExecutionException
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException, ExecutionException {
ForkJoinPool fjp = new ForkJoinPool();
CountTask ct = new CountTask(1, 100);
ForkJoinTask<Integer> rt = fjp.submit(ct);
System.out.println(rt.get());
}
/**
* 继承RecursiveTask类后需重写compute方法
*/
@Override
protected Integer compute() {
int sum=0;
/*通过计算截止数据和起始数据之间的差值来判断是否需要对任务进行拆分,THREADCOUNT数值越小拆分的任务越多*/
boolean recursion = end-start<=THREADCOUNT;
if(recursion){
for(int i=start; i<=end; i++){
sum+=i;
}
return sum;
}else{
/*拆分任务*/
//计算中间数据
int model = (end+start)/2;
CountTask leftTask = new CountTask(start, model);
CountTask rightTask = new CountTask(model+1, end);
leftTask.fork();
rightTask.fork();
int res1 = leftTask.join();
int res2 = rightTask.join();
sum=res2+res1;
}
return sum;
}
}