demo1: 使?Fork/Join来求,斐波那契数列第n项
斐波那契数列数列是?个线性递推数列,从第三项开始,每?项的值都等于
前两项之和:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89······
如果设f(n)为该数列的第n项(n∈N*),那么有:f(n) = f(n-1) + f(n-2)。
import org.junit.Test;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
/**
* Created by DELL on 2020/7/20.
*/
public class FibonacciTest {
class Fibonacci extends RecursiveTask {
int n;
public Fibonacci(int n) {
this.n = n;
}
// 主要的实现逻辑都在compute()?
@Override
protected Integer compute() {
// 这?先假设 n >= 0
if (n <= 1) {
return n;
} else {
// f(n-1)
Fibonacci f1 = new Fibonacci(n - 1);
f1.fork();
// f(n-2)
Fibonacci f2 = new Fibonacci(n - 2);
f2.fork();
// f(n) = f(n-1) + f(n-2)
return f1.join() + f2.join();
}
}
}
@Test
public void testFib() throws ExecutionException, InterruptedException {
ForkJoinPool forkJoinPool = new ForkJoinPool();
System.out.println("CPU核数:" + Runtime.getRuntime().availableProcessors());
long start = System.currentTimeMillis();
Fibonacci fibonacci = new Fibonacci(40);
Future future = forkJoinPool.submit(fibonacci);
System.out.println(future.get());
long end = System.currentTimeMillis();
System.out.println(String.format("耗时:%d millis", end - start));
}
}
输出:
CPU核数:4
计算结果:102334155
耗时:9490 millis
demo2:求1+2+3+4的结果
Fork/Join框架分割任务,将每个子任务最多执行两个数的相加,那么我们设置分割的阈值是2,由于是4个数字相加,所以Fork/Join框架会把这个任务fork成两个子任务,子任务一负责计算1+2,子任务二负责计算3+4,然后再join两个子任务的结果。因为是有结果的任务,所以必须继承RecursiveTask
importjava.util.concurrent.ExecutionException;importjava.util.concurrent.ForkJoinPool;importjava.util.concurrent.Future;importjava.util.concurrent.RecursiveTask;/***
*@authoraikq
* @date 2018年11月21日 20:37*/
public classForkJoinTaskDemo {public static voidmain(String[] args) {
ForkJoinPool pool= newForkJoinPool();
CountTask task= new CountTask(1,4);
Future result =pool.submit(task);try{
System.out.println("计算结果=" +result.get());
}catch(InterruptedException e) {
e.printStackTrace();
}catch(ExecutionException e) {
e.printStackTrace();
}
}
}class CountTask extends RecursiveTask{private static final long serialVersionUID = -7524245439872879478L;private static final int THREAD_HOLD = 2;private intstart;private intend;public CountTask(int start,intend){this.start =start;this.end =end;
}
@OverrideprotectedInteger compute() {int sum = 0;//如果任务足够小就计算
boolean canCompute = (end - start) <=THREAD_HOLD;if(canCompute){for(int i=start;i<=end;i++){
sum+=i;
}
}else{int middle = (start + end) / 2;
CountTask left= newCountTask(start,middle);
CountTask right= new CountTask(middle+1,end);//执行子任务
left.fork();
right.fork();//获取子任务结果
int lResult =left.join();int rResult =right.join();
sum= lResult +rResult;
}returnsum;
}
}