您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java JUC多線程的Fork Join Pool怎么使用”,在日常操作中,相信很多人在Java JUC多線程的Fork Join Pool怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java JUC多線程的Fork Join Pool怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
前言:在工作當中我們在計算一個很大值加上一個很大的值等等計算的時候,這時候計算機在串行計算的時候就很耗CPU,效率也很低
這時候我們可以選擇多線程分支合并 利用多個線程去計算,然后將最后各個線程的結果合并最終的結果
ForkJoinPool 分支/合并框架 工作竊取
Fork/Join 框架:就是在必要的情況下,將一個大任務,進行拆分(fork)成 若干個小任務(拆到不可再拆時),再將一個個的小任務運算的結果進 行 join 匯總。
如圖:
Fork/Join 框架與線程池的區別
? 采用 “工作竊取”模式(work-stealing): 當執行新的任務時它可以將其拆分分成更小的任務執行,并將小任務加 到線程隊列中,然后再從一個隨機線程的隊列中偷一個并把它放在自己的隊 列中。
? 相對于一般的線程池實現,fork/join框架的優勢體現在對其中包含的任務 的處理方式上.在一般的線程池中,如果一個線程正在執行的任務由于某些 原因無法繼續運行,那么該線程會處于等待狀態。而在fork/join框架實現中, 如果某個子問題由于等待另外一個子問題的完成而無法繼續運行。那么處理 該子問題的線程會主動尋找其他尚未運行的子問題來執行.這種方式減少了 線程的等待時間,提高了性能。
不多說,看代碼:
package com.atxiaodei.javajuc.jucdemo;import org.junit.Test;import java.time.Duration;import java.time.Instant;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.ForkJoinTask;import java.util.concurrent.RecursiveTask;import java.util.stream.LongStream;/** * @author wangmeng * @date 2020/9/23 * ForkJoinPool 分支/合并框架 工作竊取 * 前言:在工作當中我們在計算一個很大值加上一個很大的值等等計算的時候,這時候計算機在串行計算的時候就很耗CPU,效率也很低,這時候我們可以選擇 * 多線程分支合并 利用多個線程去計算,然后將最后各個線程的結果合并最終的結果 **/public class TestForkJoinPool線程分支合并 { public static void main(String[] args) { // 1.8 特性獲取計算 Instant start = Instant.now(); ForkJoinPool pool = new ForkJoinPool(); ForkJoinTask<Long> task = new ForkJoinSumCalculate(0L, 50000000000L); Long sum = pool.invoke(task); System.out.println(sum); Instant end = Instant.now(); System.out.println("耗費時間為:" + Duration.between(start, end).toMillis());//166-1996-10590 } @Test public void test1(){ Instant start = Instant.now(); long sum = 0L; for (long i = 0L; i <= 50000000000L; i++) { sum += i; } System.out.println(sum); Instant end = Instant.now(); System.out.println("耗費時間為:" + Duration.between(start, end).toMillis());//35-3142-15704 } //java8 新特性 @Test public void test2(){ Instant start = Instant.now(); Long sum = LongStream.rangeClosed(0L, 50000000000L) .parallel() .reduce(0L, Long::sum); System.out.println(sum); Instant end = Instant.now(); System.out.println("耗費時間為:" + Duration.between(start, end).toMillis());//1536-8118 }}// 繼承 RecursiveTask<返回類型> 實現compute方法完成分支合并class ForkJoinSumCalculate extends RecursiveTask<Long> { private static final long serialVersionUID = -259195479995561737L; private long start; private long end; private static final long THURSHOLD = 10000L; //臨界值 public ForkJoinSumCalculate(long start, long end) { this.start = start; this.end = end; } @Override protected Long compute() { long length = end - start; if(length <= THURSHOLD){ long sum = 0L; for (long i = start; i <= end; i++) { sum += i; } return sum; }else{ long middle = (start + end) / 2; ForkJoinSumCalculate left = new ForkJoinSumCalculate(start, middle); //進行拆分(這里看不到到底在哪個里面計算的值呢?好好想,好看, // 上面的概念,(拆到不可再拆時,也就是當前length小于等于10000L的時候進行計算)),同時壓入線程隊列 left.fork(); ForkJoinSumCalculate right = new ForkJoinSumCalculate(middle+1, end); right.fork(); //進行拆分,同時壓入線程隊列 return left.join() + right.join(); } }}
運行代碼,完成總結:
在進行小數值計算的時候,效率 java8新特性Stream<for迭代器<ForkJoinPool 分支合并
在進行大數值特別大的計算的時候,效率 ForkJoinPool 分支合并< java8新特性Stream<for迭代器
大數值 ForkJoinPool 分支合并效率最好,Steam還行,for迭代器特別卡,執行半分鐘
到此,關于“Java JUC多線程的Fork Join Pool怎么使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。