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();
}
}