ForkJoin
什么是ForkJoin
ForkJion 在JDK1.7,并行執行任務!提高效率,大資料量!
大資料:Map Reduce(將大任務拆分為小任務)

ForkJion 特點:作業竊取
這個里面維護的都是雙端佇列,A 執行緒沒有執行完,B執行緒執行完了,B 執行緒則去 執行A 中的(紅框)未執行完任務
ForkJion

代碼案例:
package com.forkjoin;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;
/**
* 3000 6000(ForkJoin) 9000(Stream并行流)
*/
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//test1();//8039
//test2(); //4369
test3(); //152
}
public static void test1(){
Long sum =0L;
long start = System.currentTimeMillis();
for (Long i = 1L; i < 10_0000_0000; i++) {
sum+=i;
}
long end = System.currentTimeMillis();
System.out.println("sum="+sum+"時間:"+(end -start));
}
public static void test2() throws ExecutionException, InterruptedException {
Long sum =0L;
long start = System.currentTimeMillis();
//forkJoin 池子
ForkJoinPool forkJoinPool = new ForkJoinPool();
//實體化業務方法
ForkJoinTask<Long> task = new ForkJoinDemo(0L,10_0000_0000L);
//在池子中執行業務
ForkJoinTask<Long> submit = forkJoinPool.submit(task);
sum = submit.get();
long end = System.currentTimeMillis();
System.out.println("sum="+sum+"時間:"+(end -start));
}
public static void test3() throws ExecutionException, InterruptedException {
Long sum =0L;
long start = System.currentTimeMillis();
//Stream 并行流 range 不包含后面的,rangeClosed 包含后面的
sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0, Long::sum);
long end = System.currentTimeMillis();
System.out.println("sum="+sum+"時間:"+(end -start));
}
}
package com.forkjoin;
import java.util.concurrent.RecursiveTask;
/**
*
* 求和計算的任務!
*
* 3000, 6000(ForkJoin) 9000(Stream 并行流)
* 如何使用forkJoin
* 1.forkJoinPool 通過它來執行
* 2.計算任務forkjoinPoolexecute
* 3.計算類要繼承ForkJoinTask
*
* Recursive : 發音 rekusive
*
*/
public class ForkJoinDemo extends RecursiveTask<Long> {
private Long start;
private Long end;
//臨界值
private Long temp = 10000L;
public ForkJoinDemo(Long start, Long end) {
this.start = start;
this.end = end;
}
public static void main(String[] args) {
// int sum =0;
// for (int i = 0; i < 10_0000_0000; i++) {
// sum+=i;
// }
// System.out.println(sum);
//
//
}
public void test(){
//100 -50 >50
if((end -start) >temp){
int sum =0;
for (int i = 0; i < 10_0000_0000; i++) {
sum+=i;
}
System.out.println(sum);
}
}
//計算的回傳值就是 RecursiveTask 的泛型
@Override
protected Long compute() {
//如果范圍比 1 萬還小我們就不用分支合并
if((end -start) <temp){
Long sum =0L;
for (long i =start; i <=end; i++) {
sum+=i;
}
return sum;
}else{ //forkjoin: 一個任務拆分為多個任務 ,像遞回
long middle = (start + end) / 2; //中間值
ForkJoinDemo task1 = new ForkJoinDemo(start, middle);
task1.fork(); //拆分任務,把任務壓入到執行緒佇列
ForkJoinDemo task2 = new ForkJoinDemo(middle+1, end);
task2.fork();
return task1.join() + task2 .join();
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/287904.html
標籤:其他
上一篇:js資料精度
下一篇:大資料開發-Go-陣列,切片


