Java併發的四種風味:Thread、Executor、ForkJoin和Actor
ForkJoin工具類與實現demo
1.工具類java
package thread.demo_027;
import java.util.concurrent.RecursiveTask;
public class ForkJoinWork extends RecursiveTask<Long>{ private Long start;//開始值 private Long end;//介紹值 public static final Long critical =100000L;//臨界值 public ForkJoinWork(Long start, Long end) { this.start=start; this.end=end; } @Override protected Long compute() { //判斷是否拆分 Long lenth=end-start; if(lenth<=critical){ //若是拆分完畢就相加 Long sum=0L; for (Long i = start; i <=end; i++) { sum+=i; } return sum; }else{ //沒有拆分完畢就開始拆分 Long middle=(end+start)/2;//計算2個值得中間值 ForkJoinWork right=new ForkJoinWork(start,middle); right.fork();//拆分,並壓入線程隊列 ForkJoinWork left=new ForkJoinWork(middle+1, end); left.fork(); //拆分 並加入線程隊列 //合併 return right.join()+left.join(); } } }
2.工具類實現併發
package thread.demo_027; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.Future; import java.util.concurrent.RecursiveTask; /** * Fork/Join框架demo * */ public class ForkJoinDemo { private static int THRESLOD=10;//任務閾值 /** * 求1到100萬之間的和,由於須要返回結果,因此須要繼承recursiverTask */ static class MC extends RecursiveTask<Long>{ Long sum = Long.valueOf(0); private int begin,end; public MC(int begin, int end){ this.begin=begin; this.end=end; } //表示這個任務完成後,返回的一個值 @Override protected Long compute() { //若是任務量小於閾值,就直接計算 if ((end-begin)<=THRESLOD){ for (int i = begin; i <end ; i++) { sum +=i; } }else{//若是大於1000, 就把他拆分紅兩個子任務進行fork int mid= (end+begin)/2; MC left=new MC(begin,mid);//一部分小線程 left.fork();//開啓這小部分線程 MC right= new MC(mid,end); right.fork(); Long li= left.join();//讓left任務完整完成 Long lr= right.join();//讓right任務完整完成 sum=li+lr; } return sum; } } public static void main(String[] args) throws Exception{ ForkJoinPool forkJoinPool =new ForkJoinPool();//建立他的線程池 Future<Long> ft=forkJoinPool.submit(new MC(0,10));//在線程池中進行計算 System.out.println("計算的結果是:"+ft.get()); forkJoinPool.shutdown();//關閉線程池 } }
3.原理、ForkJoin框架實現:
就是將併發的線程進行拆分、而後進行合併、可是有一個難題、好比一個複雜邏輯的
怎麼將一個線程任務、拆分多個任務、保證數據完整性與一致性。就至關於synchronized的不可見性與原子性。
框架