Java併發程式設計ForkJoin的Demo
前言
時間有限, 就先寫著,有時間補註釋
概念問題在這裡:
https://blog.csdn.net/qq_41489540/article/details/109166650
準備資料來源工具類
使用根據類準備
import java.util.Random;
/**
* 準備陣列工具類
*/
public class MakeArrayUtil {
//陣列長度 如果設定過大,會使得計算結果變為負數
public static final int ARRAY_LENGTH = 10000;
public final static int THRESHOLD = 47;
public static int[] makeArray() {
//new一個隨機數發生器
Random r = new Random();
int[] result = new int[ARRAY_LENGTH];
for (int i = 0; i < ARRAY_LENGTH; i++) {
//用隨機數填充陣列
result[i] = r.nextInt(ARRAY_LENGTH * 3);
}
return result;
}
}
不使用ForkJoin單執行緒累計工作
public class Main {
public static void main(String[] args) {
int count = 0;
int[] src = MakeArrayUtil.makeArray();
long start = System.currentTimeMillis();
for (int i = 0; i < src.length; i++) {
SleepTools.ms(1);
count = count + src[i];
}
System.out.println("總數是 " + count
+ " 耗時" + (System.currentTimeMillis() - start) + "ms");
}
}
控制檯列印結果: 總數是 150190419 耗時18051ms
花費了18051ms
使用ForkJoin累計工作
這個資料來源和上面的不使用ForkJoin單執行緒累計工作的類是一個類.所以是一個資料來源
import utils.SleepTools;
import java.util.concurrent.RecursiveTask;
public class SumTask extends RecursiveTask<Integer> {
/*閾值(拆分到多小的時候不拆分了,直接進行計算) 陣列長度除以10*/
private final static int THRESHOLD = MakeArrayUtil.ARRAY_LENGTH / 10;
private int[] src; //原始陣列
private int fromIndex;
private int toIndex;
/**
* 構造
* @param src 陣列
* @param fromIndex 陣列的起始索引
* @param toIndex 陣列的最大索引
*/
public SumTask(int[] src, int fromIndex, int toIndex) {
this.src = src;
this.fromIndex = fromIndex;
this.toIndex = toIndex;
}
/**
* 執行計算的方法
* @return
*/
@Override
protected Integer compute() {
/*任務的大小是否合適
結束索引-起始索引小於閾值了就直接彙總統計
* */
if (toIndex - fromIndex < THRESHOLD) {
int count = 0;
for (int i = fromIndex; i <= toIndex; i++) {
SleepTools.ms(1);
count = count + src[i];
}
return count; // 結果返回出去
} else {// 大於閾值 就對半拆分
//fromIndex....mid.....toIndex
int mid = (fromIndex + toIndex) / 2; //求中間值
//拆分成兩個
SumTask left = new SumTask(src, fromIndex, mid);//左半邊
SumTask right = new SumTask(src, mid + 1, toIndex);//右半邊(注意一定要中間值索引加1)
invokeAll(left, right);//把左右子任務拿到池子裡面去執行
return left.join() + right.join(); //拿到兩個子任務的值(左邊加右邊)
}
}
}
public class Main {
/**
* 統計陣列的所有的元素的和案例
* 用 ForkJoin
*/
public static void main(String[] args) {
int[] src = MakeArrayUtil.makeArray();
/*new出池的例項*/
ForkJoinPool pool = new ForkJoinPool();
/*new出Task的例項*/
SumTask innerFind = new SumTask(src, 0, src.length - 1);
long start = System.currentTimeMillis();
//開始執行
Integer invoke = pool.invoke(innerFind); //同步執行 獲取結果,會在計算之後列印下面的話
// ForkJoinTask<Integer> submit = pool.submit(innerFind); //非同步執行,會在計算完成之前列印下面的話
System.out.println("執行完成了");
//System.out.println("Task is Running.....");
Integer count = innerFind.join();
System.out.println("總數是 " + count
+ " 耗時" + (System.currentTimeMillis() - start) + "ms");
}
}
控制檯列印:
執行完成了
總數是 150759206 耗時2273ms
總結
不使用ForkJoin的情況下耗時18051ms , 使用ForkJoin的情況下耗時2273ms
相關文章
- 併發程式設計:DEMO:比較Stream和forkjoin框架的效率程式設計框架
- 併發程式設計之:ForkJoin程式設計
- java 併發程式設計Java程式設計
- Java併發程式設計Java程式設計
- Java併發程式設計---java規範與模式下的併發程式設計1.1Java程式設計模式
- 【Java併發程式設計】併發程式設計大合集-值得收藏Java程式設計
- Java併發程式設計 - 第十一章 Java併發程式設計實踐Java程式設計
- java-併發程式設計Java程式設計
- Java併發程式設計-CASJava程式設計
- Java併發程式設計:synchronizedJava程式設計synchronized
- Java 併發程式設計解析Java程式設計
- Java併發程式設計:LockJava程式設計
- Java併發程式設計-鎖及併發容器Java程式設計
- Java併發系列—併發程式設計挑戰Java程式設計
- Java併發程式設計的藝術Java程式設計
- Java對併發程式設計的支援Java程式設計
- 《java併發程式設計的藝術》併發工具類Java程式設計
- java併發程式設計系列:java併發程式設計背景知識Java程式設計
- Java併發程式設計的藝術,解讀併發程式設計的優缺點Java程式設計
- Java併發程式設計藝術Java程式設計
- Java併發程式設計實踐Java程式設計
- Java併發程式設計—ThreadLocalJava程式設計thread
- Java 併發程式設計 Executor 框架Java程式設計框架
- Java併發程式設計 -- ConditionJava程式設計
- Java併發程式設計 -- ThreadLocalJava程式設計thread
- Java併發程式設計之synchronizedJava程式設計synchronized
- Java併發程式設計基礎Java程式設計
- Java 併發程式設計要點Java程式設計
- Java併發程式設計——ThreadLocalJava程式設計thread
- java併發程式設計:同步容器Java程式設計
- Java併發程式設計實戰Java程式設計
- Java併發程式設計-synchronized指南Java程式設計synchronized
- 《java併發程式設計的藝術》併發容器和框架Java程式設計框架
- 【Java併發程式設計】一、為什麼需要學習併發程式設計?Java程式設計
- Java併發程式設計中的設計模式解析(一)Java程式設計設計模式
- Java併發程式設計之Java CAS操作Java程式設計
- Java併發程式設計:Java執行緒Java程式設計執行緒
- Java程式設計師修煉之道—併發程式設計Java程式設計師