概念
使用
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class TC51 {
public static void main(String[] args) {
//递归到最小不可分解单元,再进行计算
ForkJoinPool pool = new ForkJoinPool(5);
pool.invoke(new MyTask(5));
}
}
//实现1-n的累加
class MyTask extends RecursiveTask<Integer> {
private int n;
public MyTask(int n) {
this.n = n;
}
@Override
protected Integer compute() {
//中止条件
if (n==1) {
return 1;
}
MyTask myTask = new MyTask(n-1);
myTask.fork(); //启动一个线程去执行myTask. 例如启动第1个线程执行5-1=4
int result = n+ myTask.join(); //拿到启动的线程的结果
System.out.println("*****result:"+result);
// 例如启动第1个线程执行5-1=4;result=5+myTask(4)的返回值 5+10=15--->最后result==15
// 例如启动第2个线程执行4-1=3; result=4+myTask(3)的返回值 4+6=10 --->最后result==10
// 例如启动第3个线程执行3-1=2; result=3+myTask(2)的返回值 3+3=6 --->最后result==6
// 例如启动第4个线程执行2-1=1; result=2+myTask(1)的返回值 2+1=3 --->最后result==3
// 例如启动第5个线程执行2-1=1; return=1;
return result;
}
}
设置start和end为动态参数
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class TC52 {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(new Task1(2,6));
//20
}
}
@Slf4j(topic = "Task1")
class Task1 extends RecursiveTask<Integer>{
private int start;
private int end;
public Task1(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public String toString() {
return "Task1{" +
"start=" + start +
", end=" + end +
'}';
}
@Override
protected Integer compute() {
if (start==end) {
return end;
}
if (end-start==1) {
return end+start;
}
int mid = (end+start) / 2;
log.debug("mid={}",mid);
Task1 task1 = new Task1(start,mid);
task1.fork();
//2-4
Task1 task2 = new Task1(mid+1,end);
task2.fork();
//5-6
log.debug("info {} + {}",task1.join(),task2.join());
int result = task1.join() + task2.join();
log.debug("info {} + {} = {}",task1,task2,result);
//2-6--->2,4+5,6
//2-4-->2,3+4,4
//先计算2,3和4,4;再将结果放入2,4中与5,6一同计算
return result;
}
}
难点在任务拆分上