日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Fork_Join - Java多线程编程

發布時間:2024/4/13 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Fork_Join - Java多线程编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
線程池可以高效的執行大量的小任務:Fork/Join線程可以執行一種特殊的任務:1. 可以把一個大任務拆成多個小任務并行的執行2. Fork/Join是在JDK1.7

例如我們計算一個大數組的和:假設有一千萬個元素

我們就可以進行并行計算,然后把兩個結果加起來就是最終的結果.

如果拆成兩個數組以后,每個數組仍然很大,我們還可以進一步拆分,例如拆分四個,我們就可以讓四核的CPU并行的計算

Fork/Join的任務就是把大任務不斷地拆成小任務需要繼承JDK的RecursiveTask的類,然后復寫compute方法

在compute方法內部我們需要把一個大任務拆分多個任務,然后調用invokeAll()這個方法,同時運行兩個小任務,當兩個任務都運行結束以后,invokeAll才會返回,然后我們通過join方法獲得返回結果,最后我們把兩個結果加起來返回

package com.leon.day05;import java.util.Random; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.RecursiveTask;/*** 求和的任務繼承自RecursiveTask,返回值類型是null類型* @author Leon.Sun**/ class SumTask extends RecursiveTask<Long> {// 我們定義了一個常量,用它來指定我們如何來分解任務static final int THRESHOLD = 500;long[] array;int start;int end;// 當我們創建一個SumTask的時候,我們傳入一個數組,傳入start,endSumTask(long[] array, int start, int end) {this.array = array;this.start = start;this.end = end;}@Overrideprotected Long compute() {// 如果任務足夠小我們就直接進行計算if (end - start <= THRESHOLD) {// 如果任務足夠小,直接計算long sum = 0;for (int i = start; i < end; i++) {sum += this.array[i];try {// 在求和的時候我們使用Thread.sleep()中斷兩毫秒// 這樣我們就可以看到forkJoin執行的時間Thread.sleep(2);} catch (InterruptedException e) {}}// 返回計算的結果return sum;}// 任務太大,一分為二,把它拆成兩個子任務int middle = (end + start) / 2;System.out.println(String.format("split %d~%d ==> %d~%d, %d~%d", start,end, start, middle, middle, end));// 我們就獲得了subTask1和subTask2SumTask subtask1 = new SumTask(this.array, start, middle);SumTask subTask2 = new SumTask(this.array, middle, end);// 緊接著我們調用invokeAll方法,同時執行這兩個子任務invokeAll(subtask1, subTask2);// 然后我們通過join方法獲得兩個子任務的方法Long subresult1 = subtask1.join();Long subresult2 = subTask2.join();// 最后把兩個加起來返回Long result = subresult1 + subresult2;System.out.println("result = " + subresult1 + "+" + subresult2+ " ==> " + result);return result;} }/*** 在這個例子中,我們對一個大數組進行求和* @author Leon.Sun**/ public class ForkJoinTaskSample {static Random random = new Random(0);static long random() {return random.nextInt(1000);}public static void main(String[] args) throws Exception {// 創建1000個隨機數組成的數組// 創建一個包含1000個元素的隨機數組// 由于這個數組包含了一千個元素,所以我們在不使用forkJoin的時候,它大概需要兩秒鐘的時間,來完成求和long[] array = new long[1000];// 創建一個期望求和的值long expectedSum = 0;for (int i = 0; i < array.length; i++) {array[i] = random();expectedSum += array[i];}System.out.println("Expected sum: " + expectedSum);// fork/join// 緊接著我們創建一個ForkJoinTaskForkJoinTask<Long> task = new SumTask(array, 0, array.length);long startTime = System.currentTimeMillis();// 然后我們通過ForkJoinPool.commonPool獲得一個ForkJoinPool// 然后通過invoke方法執行這個任務Long result = ForkJoinPool.commonPool().invoke(task);long endTime = System.currentTimeMillis();// 我們打印任務執行的時間System.out.println("Fork/join sum: " + result + " in "+ (endTime - startTime));} }Expected sum: 492164 split 0~1000 ==> 0~500, 500~1000 result = 251591+240573 ==> 492164 Fork/join sum: 492164 in 1088 static final int THRESHOLD = 500;這個是表示拆分的大小 每份都是500Expected sum: 492164 split 0~1000 ==> 0~500, 500~1000 split 500~1000 ==> 500~750, 750~1000 split 0~500 ==> 0~250, 250~500 result = 120306+120267 ==> 240573 result = 127611+123980 ==> 251591 result = 251591+240573 ==> 492164 Fork/join sum: 492164 in 540

Fork/Join在JDK的內部也有一些應用:java.util.Arrays.paralleSort(array);這里就是通過Fork/Join把一個大數組進行并行排序,在多核CPU下就可以大大的提高排序的速度. 1. Fork/Join 是一種基于分治的算法:首先把大任務分解成小任務,然后再合并小任務的結果2. ForkJoinPool線程池可以把一個大任務分拆成小任務并行執行3. 我們實現一個任務類必須繼承自RecursiveTask/RecursiveAction這兩個接口的區別是RecursiveTask有返回值,RecursiveAction沒有返回值4. 我們使用Fork/Join模式可以進行并行計算提高效率

?

總結

以上是生活随笔為你收集整理的Fork_Join - Java多线程编程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。