Intel Triple-speed Ethernet IP 使用筆記(二)
阿新 • • 發佈:2022-01-07
什麼是ForkJoin 並行執行任務 提高效率(大資料量時)
大資料:MapReduce 把大任務拆分為小任務
ForkJoin
ForkJoin特點 工作竊取 維護了一個雙端佇列
當兩個執行緒同時執行時,其中一個執行緒先執行完,可以偷取未執行完執行緒的工作幫助它執行
ForkJoin操作
定義一個計算類繼承 RecursiveTask
/*求和計算*/ public class ForkJoinTest extends RecursiveTask<Long> { private Long start; private Long end; private Long temp=100000L; public ForkJoinTest(Long start, Long end) { this.start = start; this.end = end; } //如果小於臨界值,就用普通方式,否則使用forkJoin方式 @Override protected Long compute() { if(end-start<temp){ //分支合併計算 如何使用forkJoin /* * 1. forkJoinPool * 2. 計算任務,forkJoinPool.execute(ForkJoinTask task) * 3. 計算類繼承 RecursiveTask<Long> 類*/ Long sum=0L; for(Long i=start;i<=end;i++) { sum=sum+i; } return sum; }else{ long middle=(start+end)/2; ForkJoinTest task1 = new ForkJoinTest(start, middle); task1.fork(); //拆分任務,把任務壓入執行緒佇列 ForkJoinTest task2 = new ForkJoinTest(middle + 1, end); task2.fork(); return task1.join()+task2.join(); //返回結果 } } }
測試類
public class Test { public static void main(String[] args) throws ExecutionException, InterruptedException { test3(); } //普通方式 //sum=500000000500000000 時間:3594 public static void test1(){ long sum=0L; long start=System.currentTimeMillis(); for(Long i=1L;i<=10_0000_0000;i++){ sum=sum+i; } long end=System.currentTimeMillis(); System.out.println("sum="+sum+" 時間:"+(end-start)); } //ForkJoin //sum=500000000500000000 時間:4256 可以調節 public static void test2() throws ExecutionException, InterruptedException { long start=System.currentTimeMillis(); ForkJoinPool forkJoinPool = new ForkJoinPool(); ForkJoinTest task = new ForkJoinTest(0L, 10_0000_0000L); //forkJoinPool.execute(task); //執行任務 同步 ForkJoinTask<Long> submit = forkJoinPool.submit(task);//提交任務 非同步 Long sum = submit.get(); long end=System.currentTimeMillis(); System.out.println("sum="+sum+" 時間:"+(end-start)); } //Stream並行流 //sum=500000000500000000 時間:234 最優方案 public static void test3(){ long start=System.currentTimeMillis(); long sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0L, Long::sum); long end=System.currentTimeMillis(); System.out.println("sum="+sum+" 時間:"+(end-start)); } }
ForkJoin必須是在大資料量時使用