Fork /Join框架提供了一种更为有效的任务管理方式,当ForkJoinPool执行ForkJoinTask任务时可以采用同步或者异步的运行方式。
当采用同步运行方式时,把任务交给ForkJoinPool处理后不会立即返回,而是等待任务全部结束才能返回继续执行;采用异步的运行方式时,吧3任务发送到ForkJoinPool后会立马返回并继续执行。
采用不同的运行方式时,任务调用的方法时不同的。
采用invokeAll()方法会使任务被挂起等待,直到被提交到ForkJoinPool的任务处理完毕才继续执行,可见,invokeAll()方法使任务运行在同比方式中。
如果要运行在异步方式中,可以采用fork()方法,处于该方式中的ForkJoinPool不会使用工作窃取方法来提高程序的性能,在这种情况下,需要调用jion()和fork()方法来等待任务的结束,这个时候ForkJoinPool
才会使用工作窃取算法。
demo 示例:
利用Fork/Join 框架求Fibonacci数列的某一项的值。
求Fibonacci数列的公式如下:
Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
//分解、工作类
public class FibTask extends RecursiveTask<Integter>{
Integer num;
public FibTask (Integer num){
this.num = num;
}
@Override
public Integer compute(){
Integer result;
if(num<=10){
result = getValue(num);
}else{
FibTask fibTask1 = new FibTask(num-1);
FibTask fibTask2 = new FibTask(num-2);
fibTask1.fork();
fibTask2.fork();
result = fibTask1.join() + fibTask2.join();
}
return result;
}
public Integer getValue(Integer n){
Integer [] fib = {1,1,2,3,5,8,13,21,34,55,89};
return fib[n];
}
}
//测试启动类
public class Index{
public static void main(String [] args){
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Integer> fjtask = new FibTask(38);
pool.execute(fjtask);
do{
System.out.println("******************************************************");
System.out.printf("类Index:并行度:%d\n",pool.getParallelism());
System.out.printf("类Index:活动的线程数:%d\n",pool.getActiveThreadCount());
System.out.printf("类Index:任务数:%d\n",pool.getQueuedTaskCount());
System.out.printf("类Index:窃取任务数: %d\n",pool.getStealCount());
System.out.println("******************************************************");
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}while(!fjtask.isDone());
System.out.println("斐波那契的值为:"+fjtask.join() );
pool.shutdown();
}
}