黄a在线观看-黄a在线-黄a大片-黄色片在线看-黄色毛片免费-黄色大片网站

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

輕輕松松吃透Java并發(fā)fork/join框架

瀏覽:9日期:2022-08-08 17:41:42
目錄一、概述二、說(shuō)一說(shuō) RecursiveTask三、 Fork/Join框架基本使用四、工作順序圖1、ForkJoinPool構(gòu)造函數(shù)2、fork方法和join方法五、使用Fork/Join解決實(shí)際問(wèn)題1.使用歸并算法解決排序問(wèn)題2.使用Fork/Join運(yùn)行歸并算法

Fork / Join 是一個(gè)工具框架 , 其核心思想在于將一個(gè)大運(yùn)算切成多個(gè)小份 , 最大效率的利用資源 , 其主要涉及到三個(gè)類(lèi) : ForkJoinPool / ForkJoinTask / RecursiveTask

一、概述

java.util.concurrent.ForkJoinPool由Java大師Doug Lea主持編寫(xiě),它可以將一個(gè)大的任務(wù)拆分成多個(gè)子任務(wù)進(jìn)行并行處理,最后將子任務(wù)結(jié)果合并成最后的計(jì)算結(jié)果,并進(jìn)行輸出。本文中對(duì)Fork/Join框架的講解,基于JDK1.8+中的Fork/Join框架實(shí)現(xiàn),參考的Fork/Join框架主要源代碼也基于JDK1.8+。

文章將首先先談?wù)剅ecursive task,然后講解Fork/Join框架的基本使用;接著結(jié)合Fork/Join框架的工作原理來(lái)理解其中需要注意的使用要點(diǎn);最后再講解使用Fork/Join框架解決一些實(shí)際問(wèn)題。

二、說(shuō)一說(shuō) RecursiveTask

RecursiveTask 是一種 ForkJoinTask 的遞歸實(shí)現(xiàn) , 例如可以用于計(jì)算斐波那契數(shù)列 :

class Fibonacci extends RecursiveTask<Integer> { final int n; Fibonacci(int n) { this.n = n; } Integer compute() { if (n <= 1) return n; Fibonacci f1 = new Fibonacci(n - 1); f1.fork(); Fibonacci f2 = new Fibonacci(n - 2); return f2.compute() + f1.join(); } }

RecursiveTask 繼承了 ForkJoinTask 接口 ,其內(nèi)部有幾個(gè)主要的方法:

// Node 1 : 返回結(jié)果 , 存放最終結(jié)果V result;​// Node 2 : 抽象方法 compute , 用于計(jì)算最終結(jié)果protected abstract V compute();​// Node 3 : 獲取最終結(jié)果public final V getRawResult() {return result;}​// Node 4 : 最終執(zhí)行方法 , 這里是需要調(diào)用具體實(shí)現(xiàn)類(lèi)computeprotected final boolean exec() { result = compute(); return true;}

常見(jiàn)使用方式:

@ public class ForkJoinPoolService extends RecursiveTask<Integer> {​ private static final int THRESHOLD = 2; //閥值 private int start; private int end;​ public ForkJoinPoolService(Integer start, Integer end) {this.start = start;this.end = end; }​ @Override protected Integer compute() {int sum = 0;boolean canCompute = (end - start) <= THRESHOLD;if (canCompute) { for (int i = start; i <= end; i++) {sum += i; }} else { int middle = (start + end) / 2; ForkJoinPoolService leftTask = new ForkJoinPoolService(start, middle); ForkJoinPoolService rightTask = new ForkJoinPoolService(middle + 1, end); //執(zhí)行子任務(wù) leftTask.fork(); rightTask.fork(); //等待子任務(wù)執(zhí)行完,并得到其結(jié)果 Integer rightResult = rightTask.join(); Integer leftResult = leftTask.join(); //合并子任務(wù) sum = leftResult + rightResult;}return sum; }​}三、 Fork/Join框架基本使用

這里是一個(gè)簡(jiǎn)單的Fork/Join框架使用示例,在這個(gè)示例中我們計(jì)算了1-1001累加后的值:

/** * 這是一個(gè)簡(jiǎn)單的Join/Fork計(jì)算過(guò)程,將1—1001數(shù)字相加 */public class TestForkJoinPool { private static final Integer MAX = 200; static class MyForkJoinTask extends RecursiveTask<Integer> {// 子任務(wù)開(kāi)始計(jì)算的值private Integer startValue;// 子任務(wù)結(jié)束計(jì)算的值private Integer endValue;public MyForkJoinTask(Integer startValue , Integer endValue) { this.startValue = startValue; this.endValue = endValue;}@Overrideprotected Integer compute() { // 如果條件成立,說(shuō)明這個(gè)任務(wù)所需要計(jì)算的數(shù)值分為足夠小了 // 可以正式進(jìn)行累加計(jì)算了 if(endValue - startValue < MAX) {System.out.println('開(kāi)始計(jì)算的部分:startValue = ' + startValue + ';endValue = ' + endValue);Integer totalValue = 0;for(int index = this.startValue ; index <= this.endValue ; index++) { totalValue += index;}return totalValue; } // 否則再進(jìn)行任務(wù)拆分,拆分成兩個(gè)任務(wù) else {MyForkJoinTask subTask1 = new MyForkJoinTask(startValue, (startValue + endValue) / 2);subTask1.fork();MyForkJoinTask subTask2 = new MyForkJoinTask((startValue + endValue) / 2 + 1 , endValue);subTask2.fork();return subTask1.join() + subTask2.join(); }} } public static void main(String[] args) {// 這是Fork/Join框架的線程池ForkJoinPool pool = new ForkJoinPool();ForkJoinTask<Integer> taskFuture = pool.submit(new MyForkJoinTask(1,1001));try { Integer result = taskFuture.get(); System.out.println('result = ' + result);} catch (InterruptedException | ExecutionException e) { e.printStackTrace(System.out);} }}

以上代碼很簡(jiǎn)單,在關(guān)鍵的位置有相關(guān)的注釋說(shuō)明。這里本文再對(duì)以上示例中的要點(diǎn)進(jìn)行說(shuō)明。首先看看以上示例代碼的可能執(zhí)行結(jié)果:

開(kāi)始計(jì)算的部分:startValue = 1;endValue = 126開(kāi)始計(jì)算的部分:startValue = 127;endValue = 251開(kāi)始計(jì)算的部分:startValue = 252;endValue = 376開(kāi)始計(jì)算的部分:startValue = 377;endValue = 501開(kāi)始計(jì)算的部分:startValue = 502;endValue = 626開(kāi)始計(jì)算的部分:startValue = 627;endValue = 751開(kāi)始計(jì)算的部分:startValue = 752;endValue = 876開(kāi)始計(jì)算的部分:startValue = 877;endValue = 1001result = 501501

四、工作順序圖

下圖展示了以上代碼的工作過(guò)程概要,但實(shí)際上Fork/Join框架的內(nèi)部工作過(guò)程要比這張圖復(fù)雜得多,例如如何決定某一個(gè)recursive task是使用哪條線程進(jìn)行運(yùn)行;再例如如何決定當(dāng)一個(gè)任務(wù)/子任務(wù)提交到Fork/Join框架內(nèi)部后,是創(chuàng)建一個(gè)新的線程去運(yùn)行還是讓它進(jìn)行隊(duì)列等待。

所以如果不深入理解Fork/Join框架的運(yùn)行原理,只是根據(jù)之上最簡(jiǎn)單的使用例子觀察運(yùn)行效果,那么我們只能知道子任務(wù)在Fork/Join框架中被拆分得足夠小后,并且其內(nèi)部使用多線程并行完成這些小任務(wù)的計(jì)算后再進(jìn)行結(jié)果向上的合并動(dòng)作,最終形成頂層結(jié)果。不急,一步一步來(lái),我們先從這張概要的過(guò)程圖開(kāi)始討論。

輕輕松松吃透Java并發(fā)fork/join框架

圖中最頂層的任務(wù)使用submit方式被提交到Fork/Join框架中,后者將前者放入到某個(gè)線程中運(yùn)行,工作任務(wù)中的compute方法的代碼開(kāi)始對(duì)這個(gè)任務(wù)T1進(jìn)行分析。如果當(dāng)前任務(wù)需要累加的數(shù)字范圍過(guò)大(代碼中設(shè)定的是大于200),則將這個(gè)計(jì)算任務(wù)拆分成兩個(gè)子任務(wù)(T1.1和T1.2),每個(gè)子任務(wù)各自負(fù)責(zé)計(jì)算一半的數(shù)據(jù)累加,請(qǐng)參見(jiàn)代碼中的fork方法。如果當(dāng)前子任務(wù)中需要累加的數(shù)字范圍足夠小(小于等于200),就進(jìn)行累加然后返回到上層任務(wù)中。

1、ForkJoinPool構(gòu)造函數(shù)

ForkJoinPool有四個(gè)構(gòu)造函數(shù),其中參數(shù)最全的那個(gè)構(gòu)造函數(shù)如下所示:

public ForkJoinPool(int parallelism,ForkJoinWorkerThreadFactory factory,UncaughtExceptionHandler handler,boolean asyncMode) parallelism:可并行級(jí)別,F(xiàn)ork/Join框架將依據(jù)這個(gè)并行級(jí)別的設(shè)定,決定框架內(nèi)并行執(zhí)行的線程數(shù)量。并行的每一個(gè)任務(wù)都會(huì)有一個(gè)線程進(jìn)行處理,但是千萬(wàn)不要將這個(gè)屬性理解成Fork/Join框架中最多存在的線程數(shù)量,也不要將這個(gè)屬性和ThreadPoolExecutor線程池中的corePoolSize、maximumPoolSize屬性進(jìn)行比較,因?yàn)镕orkJoinPool的組織結(jié)構(gòu)和工作方式與后者完全不一樣。而后續(xù)的討論中,讀者還可以發(fā)現(xiàn)Fork/Join框架中可存在的線程數(shù)量和這個(gè)參數(shù)值的關(guān)系并不是絕對(duì)的關(guān)聯(lián)(有依據(jù)但并不全由它決定)。 factory:當(dāng)Fork/Join框架創(chuàng)建一個(gè)新的線程時(shí),同樣會(huì)用到線程創(chuàng)建工廠。只不過(guò)這個(gè)線程工廠不再需要實(shí)現(xiàn)ThreadFactory接口,而是需要實(shí)現(xiàn)ForkJoinWorkerThreadFactory接口。后者是一個(gè)函數(shù)式接口,只需要實(shí)現(xiàn)一個(gè)名叫newThread的方法。在Fork/Join框架中有一個(gè)默認(rèn)的ForkJoinWorkerThreadFactory接口實(shí)現(xiàn):DefaultForkJoinWorkerThreadFactory。 handler:異常捕獲處理器。當(dāng)執(zhí)行的任務(wù)中出現(xiàn)異常,并從任務(wù)中被拋出時(shí),就會(huì)被handler捕獲。 asyncMode:這個(gè)參數(shù)也非常重要,從字面意思來(lái)看是指的異步模式,它并不是說(shuō)Fork/Join框架是采用同步模式還是采用異步模式工作。Fork/Join框架中為每一個(gè)獨(dú)立工作的線程準(zhǔn)備了對(duì)應(yīng)的待執(zhí)行任務(wù)隊(duì)列,這個(gè)任務(wù)隊(duì)列是使用數(shù)組進(jìn)行組合的雙向隊(duì)列。即是說(shuō)存在于隊(duì)列中的待執(zhí)行任務(wù),即可以使用先進(jìn)先出的工作模式,也可以使用后進(jìn)先出的工作模式。

輕輕松松吃透Java并發(fā)fork/join框架

當(dāng)asyncMode設(shè)置為ture的時(shí)候,隊(duì)列采用先進(jìn)先出方式工作;反之則是采用后進(jìn)先出的方式工作,該值默認(rèn)為false

......asyncMode ? FIFO_QUEUE : LIFO_QUEUE,......

ForkJoinPool還有另外兩個(gè)構(gòu)造函數(shù),一個(gè)構(gòu)造函數(shù)只帶有parallelism參數(shù),既是可以設(shè)定Fork/Join框架的最大并行任務(wù)數(shù)量;另一個(gè)構(gòu)造函數(shù)則不帶有任何參數(shù),對(duì)于最大并行任務(wù)數(shù)量也只是一個(gè)默認(rèn)值——當(dāng)前操作系統(tǒng)可以使用的CPU內(nèi)核數(shù)量(Runtime.getRuntime().availableProcessors())。實(shí)際上ForkJoinPool還有一個(gè)私有的、原生構(gòu)造函數(shù),之上提到的三個(gè)構(gòu)造函數(shù)都是對(duì)這個(gè)私有的、原生構(gòu)造函數(shù)的調(diào)用。

......private ForkJoinPool(int parallelism, ForkJoinWorkerThreadFactory factory, UncaughtExceptionHandler handler, int mode, String workerNamePrefix) {this.workerNamePrefix = workerNamePrefix;this.factory = factory;this.ueh = handler;this.config = (parallelism & SMASK) | mode;long np = (long)(-parallelism); // offset ctl countsthis.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK); }......

如果你對(duì)Fork/Join框架沒(méi)有特定的執(zhí)行要求,可以直接使用不帶有任何參數(shù)的構(gòu)造函數(shù)。也就是說(shuō)推薦基于當(dāng)前操作系統(tǒng)可以使用的CPU內(nèi)核數(shù)作為Fork/Join框架內(nèi)最大并行任務(wù)數(shù)量,這樣可以保證CPU在處理并行任務(wù)時(shí),盡量少發(fā)生任務(wù)線程間的運(yùn)行狀態(tài)切換(實(shí)際上單個(gè)CPU內(nèi)核上的線程間狀態(tài)切換基本上無(wú)法避免,因?yàn)椴僮飨到y(tǒng)同時(shí)運(yùn)行多個(gè)線程和多個(gè)進(jìn)程)。

2、fork方法和join方法

Fork/Join框架中提供的fork方法和join方法,可以說(shuō)是該框架中提供的最重要的兩個(gè)方法,它們和parallelism“可并行任務(wù)數(shù)量”配合工作,可以導(dǎo)致拆分的子任務(wù)T1.1、T1.2甚至TX在Fork/Join框架中不同的運(yùn)行效果。例如TX子任務(wù)或等待其它已存在的線程運(yùn)行關(guān)聯(lián)的子任務(wù),或在運(yùn)行TX的線程中“遞歸”執(zhí)行其它任務(wù),又或者啟動(dòng)一個(gè)新的線程運(yùn)行子任務(wù)……

fork方法用于將新創(chuàng)建的子任務(wù)放入當(dāng)前線程的work queue隊(duì)列中,F(xiàn)ork/Join框架將根據(jù)當(dāng)前正在并發(fā)執(zhí)行ForkJoinTask任務(wù)的ForkJoinWorkerThread線程狀態(tài),決定是讓這個(gè)任務(wù)在隊(duì)列中等待,還是創(chuàng)建一個(gè)新的ForkJoinWorkerThread線程運(yùn)行它,又或者是喚起其它正在等待任務(wù)的ForkJoinWorkerThread線程運(yùn)行它。

這里面有幾個(gè)元素概念需要注意,F(xiàn)orkJoinTask任務(wù)是一種能在Fork/Join框架中運(yùn)行的特定任務(wù),也只有這種類(lèi)型的任務(wù)可以在Fork/Join框架中被拆分運(yùn)行和合并運(yùn)行。ForkJoinWorkerThread線程是一種在Fork/Join框架中運(yùn)行的特性線程,它除了具有普通線程的特性外,最主要的特點(diǎn)是每一個(gè)ForkJoinWorkerThread線程都具有一個(gè)獨(dú)立的任務(wù)等待隊(duì)列(work queue),這個(gè)任務(wù)隊(duì)列用于存儲(chǔ)在本線程中被拆分的若干子任務(wù)。

輕輕松松吃透Java并發(fā)fork/join框架

join方法用于讓當(dāng)前線程阻塞,直到對(duì)應(yīng)的子任務(wù)完成運(yùn)行并返回執(zhí)行結(jié)果。或者,如果這個(gè)子任務(wù)存在于當(dāng)前線程的任務(wù)等待隊(duì)列(work queue)中,則取出這個(gè)子任務(wù)進(jìn)行“遞歸”執(zhí)行。其目的是盡快得到當(dāng)前子任務(wù)的運(yùn)行結(jié)果,然后繼續(xù)執(zhí)行。

五、使用Fork/Join解決實(shí)際問(wèn)題

之前所舉的的例子是使用Fork/Join框架完成1-1000的整數(shù)累加。這個(gè)示例如果只是演示Fork/Join框架的使用,那還行,但這種例子和實(shí)際工作中所面對(duì)的問(wèn)題還有一定差距。本篇文章我們使用Fork/Join框架解決一個(gè)實(shí)際問(wèn)題,就是高效排序的問(wèn)題。

1.使用歸并算法解決排序問(wèn)題

排序問(wèn)題是我們工作中的常見(jiàn)問(wèn)題。目前也有很多現(xiàn)成算法是為了解決這個(gè)問(wèn)題而被發(fā)明的,例如多種插值排序算法、多種交換排序算法。而并歸排序算法是目前所有排序算法中,平均時(shí)間復(fù)雜度較好(O(nlgn)),算法穩(wěn)定性較好的一種排序算法。它的核心算法思路將大的問(wèn)題分解成多個(gè)小問(wèn)題,并將結(jié)果進(jìn)行合并。

輕輕松松吃透Java并發(fā)fork/join框架

整個(gè)算法的拆分階段,是將未排序的數(shù)字集合,從一個(gè)較大集合遞歸拆分成若干較小的集合,這些較小的集合要么包含最多兩個(gè)元素,要么就認(rèn)為不夠小需要繼續(xù)進(jìn)行拆分。

那么對(duì)于一個(gè)集合中元素的排序問(wèn)題就變成了兩個(gè)問(wèn)題:1、較小集合中最多兩個(gè)元素的大小排序;2、如何將兩個(gè)有序集合合并成一個(gè)新的有序集合。第一個(gè)問(wèn)題很好解決,那么第二個(gè)問(wèn)題是否會(huì)很復(fù)雜呢?實(shí)際上第二個(gè)問(wèn)題也很簡(jiǎn)單,只需要將兩個(gè)集合同時(shí)進(jìn)行一次遍歷即可完成——比較當(dāng)前集合中最小的元素,將最小元素放入新的集合,它的時(shí)間復(fù)雜度為O(n):

輕輕松松吃透Java并發(fā)fork/join框架

以下是歸并排序算法的簡(jiǎn)單實(shí)現(xiàn):

package test.thread.pool.merge;import java.util.Arrays;import java.util.Random;/** * 歸并排序 * @author yinwenjie */public class Merge1 { private static int MAX = 10000; private static int inits[] = new int[MAX]; // 這是為了生成一個(gè)數(shù)量為MAX的隨機(jī)整數(shù)集合,準(zhǔn)備計(jì)算數(shù)據(jù) // 和算法本身并沒(méi)有什么關(guān)系 static {Random r = new Random();for(int index = 1 ; index <= MAX ; index++) { inits[index - 1] = r.nextInt(10000000);} } public static void main(String[] args) {long beginTime = System.currentTimeMillis();int results[] = forkits(inits); long endTime = System.currentTimeMillis();// 如果參與排序的數(shù)據(jù)非常龐大,記得把這種打印方式去掉System.out.println('耗時(shí)=' + (endTime - beginTime) + ' | ' + Arrays.toString(results)); } // 拆分成較小的元素或者進(jìn)行足夠小的元素集合的排序 private static int[] forkits(int source[]) {int sourceLen = source.length;if(sourceLen > 2) { int midIndex = sourceLen / 2; int result1[] = forkits(Arrays.copyOf(source, midIndex)); int result2[] = forkits(Arrays.copyOfRange(source, midIndex , sourceLen)); // 將兩個(gè)有序的數(shù)組,合并成一個(gè)有序的數(shù)組 int mer[] = joinInts(result1 , result2); return mer;} // 否則說(shuō)明集合中只有一個(gè)或者兩個(gè)元素,可以進(jìn)行這兩個(gè)元素的比較排序了else { // 如果條件成立,說(shuō)明數(shù)組中只有一個(gè)元素,或者是數(shù)組中的元素都已經(jīng)排列好位置了 if(sourceLen == 1|| source[0] <= source[1]) {return source; } else {int targetp[] = new int[sourceLen];targetp[0] = source[1];targetp[1] = source[0];return targetp; }} } /** * 這個(gè)方法用于合并兩個(gè)有序集合 * @param array1 * @param array2 */ private static int[] joinInts(int array1[] , int array2[]) {int destInts[] = new int[array1.length + array2.length];int array1Len = array1.length;int array2Len = array2.length;int destLen = destInts.length;// 只需要以新的集合destInts的長(zhǎng)度為標(biāo)準(zhǔn),遍歷一次即可for(int index = 0 , array1Index = 0 , array2Index = 0 ; index < destLen ; index++) { int value1 = array1Index >= array1Len?Integer.MAX_VALUE:array1[array1Index]; int value2 = array2Index >= array2Len?Integer.MAX_VALUE:array2[array2Index]; // 如果條件成立,說(shuō)明應(yīng)該取數(shù)組array1中的值 if(value1 < value2) {array1Index++;destInts[index] = value1; } // 否則取數(shù)組array2中的值 else {array2Index++;destInts[index] = value2; }}return destInts; }}

以上歸并算法對(duì)1萬(wàn)條隨機(jī)數(shù)進(jìn)行排序只需要2-3毫秒,對(duì)10萬(wàn)條隨機(jī)數(shù)進(jìn)行排序只需要20毫秒左右的時(shí)間,對(duì)100萬(wàn)條隨機(jī)數(shù)進(jìn)行排序的平均時(shí)間大約為160毫秒(這還要看隨機(jī)生成的待排序數(shù)組是否本身的凌亂程度)。可見(jiàn)歸并算法本身是具有良好的性能的。使用JMX工具和操作系統(tǒng)自帶的CPU監(jiān)控器監(jiān)視應(yīng)用程序的執(zhí)行情況,可以發(fā)現(xiàn)整個(gè)算法是單線程運(yùn)行的,且同一時(shí)間CPU只有單個(gè)內(nèi)核在作為主要的處理內(nèi)核工作:

JMX中觀察到的線程情況:

輕輕松松吃透Java并發(fā)fork/join框架

CPU的運(yùn)作情況:

輕輕松松吃透Java并發(fā)fork/join框架

2.使用Fork/Join運(yùn)行歸并算法

但是隨著待排序集合中數(shù)據(jù)規(guī)模繼續(xù)增大,以上歸并算法的代碼實(shí)現(xiàn)就有一些力不從心了,例如以上算法對(duì)1億條隨機(jī)數(shù)集合進(jìn)行排序時(shí),耗時(shí)為27秒左右。

接著我們可以使用Fork/Join框架來(lái)優(yōu)化歸并算法的執(zhí)行性能,將拆分后的子任務(wù)實(shí)例化成多個(gè)ForkJoinTask任務(wù)放入待執(zhí)行隊(duì)列,并由Fork/Join框架在多個(gè)ForkJoinWorkerThread線程間調(diào)度這些任務(wù)。如下圖所示:

輕輕松松吃透Java并發(fā)fork/join框架

以下為使用Fork/Join框架后的歸并算法代碼,請(qǐng)注意joinInts方法中對(duì)兩個(gè)有序集合合并成一個(gè)新的有序集合的代碼,是沒(méi)有變化的可以參見(jiàn)本文上一小節(jié)中的內(nèi)容。所以在代碼中就不再贅述了:

....../** * 使用Fork/Join框架的歸并排序算法 * @author yinwenjie */public class Merge2 { private static int MAX = 100000000; private static int inits[] = new int[MAX]; // 同樣進(jìn)行隨機(jī)隊(duì)列初始化,這里就不再贅述了 static {...... } public static void main(String[] args) throws Exception { // 正式開(kāi)始long beginTime = System.currentTimeMillis();ForkJoinPool pool = new ForkJoinPool();MyTask task = new MyTask(inits);ForkJoinTask<int[]> taskResult = pool.submit(task);try { taskResult.get();} catch (InterruptedException | ExecutionException e) { e.printStackTrace(System.out);}long endTime = System.currentTimeMillis();System.out.println('耗時(shí)=' + (endTime - beginTime)); } /** * 單個(gè)排序的子任務(wù) * @author yinwenjie */ static class MyTask extends RecursiveTask<int[]> {private int source[];public MyTask(int source[]) { this.source = source;}/* (non-Javadoc) * @see java.util.concurrent.RecursiveTask#compute() */@Overrideprotected int[] compute() { int sourceLen = source.length; // 如果條件成立,說(shuō)明任務(wù)中要進(jìn)行排序的集合還不夠小 if(sourceLen > 2) {int midIndex = sourceLen / 2;// 拆分成兩個(gè)子任務(wù)MyTask task1 = new MyTask(Arrays.copyOf(source, midIndex));task1.fork();MyTask task2 = new MyTask(Arrays.copyOfRange(source, midIndex , sourceLen));task2.fork();// 將兩個(gè)有序的數(shù)組,合并成一個(gè)有序的數(shù)組int result1[] = task1.join();int result2[] = task2.join();int mer[] = joinInts(result1 , result2);return mer; } // 否則說(shuō)明集合中只有一個(gè)或者兩個(gè)元素,可以進(jìn)行這兩個(gè)元素的比較排序了 else {// 如果條件成立,說(shuō)明數(shù)組中只有一個(gè)元素,或者是數(shù)組中的元素都已經(jīng)排列好位置了if(sourceLen == 1 || source[0] <= source[1]) { return source;} else { int targetp[] = new int[sourceLen]; targetp[0] = source[1]; targetp[1] = source[0]; return targetp;} }}private int[] joinInts(int array1[] , int array2[]) { // 和上文中出現(xiàn)的代碼一致} }}

使用Fork/Join框架優(yōu)化后,同樣執(zhí)行1億條隨機(jī)數(shù)的排序處理時(shí)間大約在14秒左右,當(dāng)然這還和待排序集合本身的凌亂程度、CPU性能等有關(guān)系。但總體上這樣的方式比不使用Fork/Join框架的歸并排序算法在性能上有30%左右的性能提升。以下為執(zhí)行時(shí)觀察到的CPU狀態(tài)和線程狀態(tài):

JMX中的內(nèi)存、線程狀態(tài):

輕輕松松吃透Java并發(fā)fork/join框架

CPU使用情況:

輕輕松松吃透Java并發(fā)fork/join框架

除了歸并算法代碼實(shí)現(xiàn)內(nèi)部可優(yōu)化的細(xì)節(jié)處,使用Fork/Join框架后,我們基本上在保證操作系統(tǒng)線程規(guī)模的情況下,將每一個(gè)CPU內(nèi)核的運(yùn)算資源同時(shí)發(fā)揮了出來(lái)。

到此這篇關(guān)于輕輕松松吃透Java并發(fā)fork/join框架的文章就介紹到這了,更多相關(guān)Java fork/join框架內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 亚洲精品av一二三区无码 | 处破女av一区二区 | 日韩毛片在线免费观看 | 五月天综合视频 | 青草成人| 成人动作片在线观看 | 精品乱码久久久久久中文字幕 | 成人www | 国产精品伦一区二区在线 | 久久亚洲精品成人av无码网站 | 免费观看全黄做爰大片国产 | 日本aaaa大片免费观看入口 | 69免费视频| 91热爆在线 | 少妇性bbb搡bbb爽爽爽 | 国产又粗又大又黄 | 丰满少妇高潮在线观看 | 国产精品美女www爽爽爽软件 | 全部av―极品视觉盛宴 | 麻豆黄色影院 | 欧美亚洲综合视频 | 青青草免费视频在线观 | 伊人手机视频 | 久久99国产精品成人 | 奇米影视一区二区三区 | 小h片免费观看久久久久 | 国产精品成人va在线观看 | 国产a国产国产片 | av网址网站 | 免费在线观看小视频 | 成年男女免费视频网站 | 婷婷伊人综合中文字幕 | 亚洲色图清纯唯美 | 丰满少妇一级 | 成人影片在线播放 | 亚洲欧洲精品视频 | 亚洲国产aⅴ成人精品无吗 亚洲国产aaa | 成人做爰69片免费看网站野花 | 一个人看的www日本高清视频 | 成人五区 | 欧美成人一区二区三区 | www国产成人 | 欧美日韩亚洲国产精品 | 五月婷婷综合激情网 | 久久精品无码专区免费 | 亚洲一区二区三区偷拍女厕 | 亚洲精品久久久蜜桃网站 | 亚洲第一成人区av桥本有菜 | 国产91精选 | 久久久欧美 | 97久久草草超级碰碰碰 | 992tv国产精品免费观看 | 欧美精品一区二区三区四区 | 一边摸一边添高潮av | 久久天天躁狠狠躁夜夜网站 | 久久免费播放视频 | 蜜桃日本免费看mv免费版 | 精品国产a∨无码一区二区三区 | 免费看av网| www啪啪| 狠狠97人人婷婷五月 | 国产区在线看 | 国产一区二区三区网站 | 男人和女人黄 色大片 | 偷国产乱人伦偷精品视频 | 免费在线观看一区 | 在线视频 中文字幕 | 国产精品久久久久久久久婷婷 | 香蕉久久a毛片 | 黑人老外猛进华人美女 | 国产高清成人久久 | 亚洲精品久久久久中文字幕 | 一交一性一色一伦一区二 | 精品美女在线观看 | 国产人成视频在线视频 | 国产亚洲精品精品国产亚洲综合 | 片毛片| 国产又粗又黄又爽又硬的免费视频 | 欧美视频三区 | 偷拍夫妻性生活 | 欧美三日本三级少妇99 | 精品国产乱码久久久软件使用方法 | 国产午夜三级一区二区三 | 天天舔天天射天天干 | 午夜激情网址 | 国产无遮挡免费观看视频网站 | 国人天堂va在线观看免费 | 国产区视频在线 | 日本19禁啪啪免费观看www | 天堂中文在线观看 | 国产精品免费久久久久影院仙踪林 | 寂寞寡妇让我吃奶 | 永久免费汤不热视频 | 成人国产福利a无限看 | 国产日产精品久久久久快鸭 | av在线网址大全 | av在线亚洲欧洲日产一区二区 | 天天鲁一鲁摸一摸爽一爽 | 欧美乱妇视频 | 精品国精品国产自在久国产87 | 国产精品久久久久久久久久98 | 九九国产精品视频 | 国产伦精品一区二区三区视频网站 | 中文字幕精品国产 | 亚洲精品美女久久久久网站 | 国产成人精品福利 | 亚洲狠狠婷婷综合久久久久图片 | 欧美三级a| 亚洲妓女综合网99 | 波多野结衣女同 | 电车痴汉在线观看 | 一区黄色 | 免费观看又色又爽又黄的崩锅 | 成人在线视频中文字幕 | 国产精品久久久久久久妇女 | 日本一码二码三码在线 | 黄色大片a级 | 在线天堂www在线国语对白 | 91精品国产色综合久久久蜜香臀 | 国产视频一二三区 | 欧美精品一区二区三区久久久竹菊 | 国产精品噜噜噜66网站 | 日日骚av| 成年人免费在线观看 | 国产美女在线播放 | 中文字幕第10页 | 777毛片 | 成年人的视频网站 | 扒开双腿被两个男人玩弄视频 | 国产免费一级视频 | 国产成人无码a区在线观看视频 | 91精品国产美女在线观看 | 色偷偷偷久久伊人大杳蕉 | 中文字幕人妻无码系列第三区 | 无码乱肉视频免费大全合集 | 日本三级排行榜 | 香蕉影音 | 欧美疯狂xxxxxbbbbb| 亚洲产国偷v产偷自拍网址 亚洲超丰满肉感bbw | 日韩影音 | 免费观看一级黄色片 | 亚洲影院在线播放 | 久操青青 | 日本一级吃奶淫片免费 | 内射国产内射夫妻免费频道 | 精品国产一 | 蜜桃网站入口在线进入 | 91少妇丨porny丨| 制服诱惑一区 | 沦为黑人姓奴的少妇 | 欧美黄色一区二区 | 久草网址| 欧产日产国产精品视频 | 亚洲成人毛片 | 大胸美女被吃奶爽死视频 | 久久精品国产亚洲5555 | 麻豆欧美 | 欧美性xxxx极品hd欧美风情 | 在线天堂中文www视软件 | 四虎4545www精品视频 | 成人黄色一级片 | 国产亚洲精品久久久久久牛牛 | 亚洲天堂一级片 | 加勒比精品 | 国内精品伊人久久久久7777 | 亚洲xx网 | 国产97免费视频 | 图片区小说区区国产明星 | 欧美大片大全 | 97视频人人 | 99久久99| 国产网站一区 | 日本三级吃奶头添泬无码苍井空 | 日剧再来一次第十集 | 色悠久久久| 51色视频| 免费黄色91| 久久久久综合网 | 久久久久久久久福利 | 黄色录像一级大片 | 成人网站在线进入爽爽爽 | 国产三级韩国三级日本带黄 | 日韩美女视频一区 | 久久国产成人午夜av影院 | 无码国产69精品久久久久同性 | 九九九九九伊人 | 日韩v欧美v日本v亚洲v国产v | 一道本在线视频 | 一二三四社区在线中文视频 | 久青草影院在线观看国产 | 无码中文av有码中文a | 久久天天躁狠狠躁夜夜97 | 亚洲精品久久久久久下一站 | 综合久久久 | 苍井空一区二区波多野结衣av | 国产成人黄色片 | 国模少妇一区二区三区 | 亚洲蜜桃av | 这里只有精品在线观看 | 双腿张开被9个黑人调教影片 | 日本三级黄在线观看 | 含紧一点h边做边走动免费视频 | 成人自拍偷拍 | 国产av精国产传媒 | 中国女人一级一次看片 | 99热这里只有精 | 韩国r级大尺度激情做爰外出 | 蜜臀99久久精品久久久久久软件 | 在线激情小视频 | 免费观看午夜视频 | 国产精品igao视频网网址不卡日韩 | 欧美在线看片a免费观看 | 精品自拍第一页 | 欧美成人精品激情在线观看 | 欧美麻豆久久久久久中文 | 精品无码国产污污污免费 | 香蕉婷婷 | 亚洲第一女人av | 九九亚洲精品 | 亚洲成av人影院在线观看 | 色婷五月| 免费又黄又粗又爽大片69 | 超级黄色片 | 99久久人人爽亚洲精品美女 | 免费播放av | 国产精品ⅴa有声小说 | 亚洲女人的天堂 | 欧美日韩性生活视频 | 天天摸天天干天天操 | 中文字幕1| 亚洲性色av私人影院无码 | 99视频网 | 欧美噜噜久久久xxx 久久精品一区二区免费播放 | 日韩小视频网站 | 99国产精品免费播放 | 三级裸体视频 | 国产成人区 | 乱h高h3p诱欢 | www日本xxxx| 国产调教丨ⅴk | 91极品美女 | 一本不卡av | 久久精品国产精品国产一区 | 黄色录像片子 | 手机看片99 | 最新免费中文字幕 | 最新毛片基地 | 九九热在线观看 | 亚洲乱码国产乱码精品精大量 | 蜜臀中文字幕 | 日本黄色成人 | 夜夜躁很很躁日日躁麻豆 | 日本无遮真人祼交视频 | 国产成人精品日本亚洲 | 宅男噜噜噜66网站在线观看 | 露脸叫床粗话东北少妇 | 日韩视频在线观看一区二区 | 欧美3p两根一起进高清免费视频 | 欧美黑人疯狂性受xxxxx喷水 | 白嫩少妇激情无码 | 国产精品爽爽ⅴa在线观看 国产精品亚洲精品日韩已方 | 成人影视在线看 | 一区综合 | 国模无码视频一区二区三区 | 国产一区二区三区四区五区精品 | 最近2019中文字幕大全第二页 | 欧美丰满大乳大屁股毛片图片 | 日韩视频在线观看视频 | 国产精品无码无片在线观看 | 成人深夜福利 | 成人黄色激情网 | 爱豆国产剧免费观看大全剧集 | 成人无码视频在线观看网址 | 日日躁夜夜躁人人揉av五月天 | 国产欧美日韩一区二区加勒比 | 人人搞人人爱 | 久久不见久久见免费影院 | 国内精品一区二区三区不卡 | 免费大片黄在线观看 | 亚洲国产www | 美女撒尿毛片视频免费看 | 一区二区三区国产 | www.av在线免费观看 | 久久久成人免费 | 91在线91拍拍在线91 | 日韩精品一区二区三区四区在线观看 | 又粗又长又大又爽又黄少妇毛片 | 国内精品一区二区 | 色婷婷在线视频 | 国产精自产拍久久久久久蜜 | 人人妻人人澡人人爽秒播 | 午夜精品一区二区三区在线播放 | 饥渴丰满的少妇喷潮 | 精品国产91久久久久久浪潮蜜月 | 美玉足脚交一区二区三区图片 | 免费女同毛片在线观看 | 国产在线观看一区二区三区 | 欧美一区二区三区在线播放 | 影音先锋每日av色资源站 | 国产女黄3片 | 高h肉辣动漫h在线观看 | 老美黑人狂躁亚洲女 | 日本动漫做毛片一区二区 | 国产精品乱码人妻一区二区三区 | 91久久久久久久久久 | 免费观看性生活大片3 | 国产精品麻豆欧美日韩ww | 狠狠gao| 欧洲熟妇色xxxx欧美老妇软件 | 亚洲精品蜜夜内射 | 中文字幕日韩一区 | 亚洲天堂视频在线观看 | 美女扒开奶罩露出奶头视频网站 | www嫩草| 日韩中文字幕成人免费视频 | 久久久国产精华液999999 | 日本一二三不卡视频 | 亚洲第三色 | 欧美成人三级在线播放 | 男女18禁啪啪无遮挡激烈网站 | 免费观看全黄做爰大片国产 | 欧洲亚洲自拍 | 三级av在线播放 | 久久久久久久99 | 羞羞视频入口 | 小说区 图片区色 综合区 | 日本欧美www | 欧美日韩一区二区三区视频播放 | 成人自拍视频网站 | 老妇裸体性激交老太视频 | 天天尻| 国产精品99久久久久久久女警 | 久久综合综合久久综合 | 99在线精品免费视频 | 日日噜噜噜夜夜爽爽狠狠小说 | 欧美亚洲第一区 | 国产乱妇乱子在线播视频播放网站 | 丰满人妻熟妇乱又伦精品软件 | 国产99久久 | 国产精选第一页 | 亚洲视频免费观看 | 国产裸体视频 | 国产人妖ts重口系列喝尿视频 | 一区二区在线免费看 | 婷婷综合少妇啪啪喷水动态小说 | 精品久久久久久久久久久久包黑料 | 波多野结衣乳巨码无在线观看 | 18禁网站免费无遮挡无码中文 | 国产乱老熟视频网站 视频 国产乱了实正在真 | 国产精品精品久久久久久甜蜜软件 | 免费观看黄色一级视频 | 日韩黄色短视频 | 91黄视频在线观看 | 97视频入口 | 91传媒入口 | 日韩精品一区二 | 欧美高清在线一区 | 欧美三级视频 | 狠狠躁夜夜躁人人爽天天5 中国china露脸自拍性hd | 无码日韩精品一区二区免费 | 老司机午夜影院 | 久久这里有| 亚洲va欧美va人人爽午夜 | 色av永久无码影院av | 自拍偷在线精品自拍偷99 | 欧美人成在线 | 亚洲精品久久久久午夜福禁果tⅴ | 黄色片免费看 | 国产美女裸体无遮挡免费视频 | 国产一区二区精品丝袜 | 国产精品99精品久久免费 | 国产亚洲精品美女久久久 | 日日干日日插 | 日韩毛片一级 | 国产亚洲黑人性受xxxx精品 | 97干在线 | 麻豆精品久久久久久久99蜜桃 | 亚洲欧美自拍偷拍 | 国产精品xxxxxx | 成人情趣片在线观看免费 | 亚州av网| 日韩精品四区 | 伊人黄 | 中文字幕人妻第一区 | 4hu四虎永久在线影院 | 真实的国产乱ⅹxxx66小说 | 91成人久久 | 欧美日韩中文在线 | 午夜在线影院 | 中国女人和老外的毛片 | 亚洲精品乱码久久久久红杏 | 啪啪中文字幕 | 插少妇视频 | 精品国产1区2区3区 精品国产31久久久久久 | 日本一区二区三区视频在线 | 女人裸体偷拍全过程 | 久久午夜福利无码1000合集 | 亚洲男女在线 | 国产午夜精品一区理论片飘花 | 欧美性tv | 精品国产一区二区三区四区 | 黄色片子看看 | 久久精品人妻无码一区二区三区 | 中文字幕一区二区三区手机版 | 高潮毛片又色又爽免费 | 窝窝人体色www | 国产精品久久毛片av大全日韩 | 亚洲精品一区二区冲田杏梨 | 国产一区二区三区乱码在线观看 | 成人在线播放av | 国产九色在线播放九色 | 99热成人| 久久精品一区二区三 | 日本裸体xx少妇18在线 | 日日摸日日碰夜夜爽无码 | 中文字幕av日韩精品一区二区 | 日本丰满大乳奶做爰 | 可以直接看的毛片 | 欧洲大片免费 | 1000午夜黄三级 | 日本一区二区三区免费视频 | 亚洲成av人的天堂在线观看 | 四虎在线免费播放 | 猫咪av成人永久网站在线观看 | 中文字幕成人在线 | 欧美成人在线免费 | 国产精品美女久久久网av | 特大黑人巨交吊性xxxxhd | 波多野结衣免费在线视频 | 国产高潮国产高潮久久久91 | 国产精品视频免费在线观看 | 黄色片网战 | 韩国毛片网站 | 久久精品成人免费观看 | 国产一级二级在线观看 | 在办公室被c到呻吟的动态图 | 国产高清免费 | 美一女一无一伦一性一交 | 亚洲 制服 丝袜 无码 | 水蜜桃亚洲一二三四在线 | 少妇又紧又色又爽又刺激视频网站 | 中文字幕一区二区人妻性色 | 无码av动漫精品一区二区免费 | 永久免费不卡在线观看黄网站 | 今夜无人入睡在线观看 | 日本少妇爱做按摩xxxⅹ | 国产普通话bbwbbwbbw | 国产精品成 | 超碰九七在线 | 婷婷午夜 | 久久久久久曰本av免费免费 | 国产涩涩 | 色综合久久久久久久久久 | 美女网站免费视频 | 97精品在线| 97国产精| 成人影片在线免费观看 | 久久久久久久久亚洲 | 精品亚洲成a人无码成a在线观看 | 中文字幕精品在线观看 | 亚洲在线看 | 激情亚洲一区国产精品 | 国产第一页在线观看 | 无码少妇一区二区三区芒果 | 人间水蜜桃av五月色 | 免费看亚洲 | 久久成人免费网站 | 国产99久久九九精品的功能介绍 | 国产乱人激情h在线观看 | 亚洲天堂男| 久久精品国产一区二区三区 | 香蕉精品视频在线观看 | 特黄特色大片免费视频观看 | yy111111少妇无码理论片 | 欧美极品少妇xxxxⅹ猛交 | 婷婷激情图片 | 国产又黄又大视频 | 三八激情网 | 巨胸喷奶水www久久久免费动漫 | 97无人区码一码二码三码 | 午夜影院在线 | 国产精品高潮呻吟久久久 | 亚洲狼人精品一区二区三区 | 美女久久久久久久 | 无码专区一va亚洲v专区在线 | 色欲狠狠躁天天躁无码中文字幕 | 青青草成人免费视频 | 不卡精品视频 | 最新2020无码中文字幕在线视频 | 一本一道精品欧美中文字幕 | 污污视频网站在线免费观看 | 欧美综合天天夜夜久久 | 亚洲色欲综合一区二区三区 | 日韩成人专区 | 自拍偷拍精品 | 中文字幕日韩在线播放 | 免费看a毛片 | 亚洲涩网 | 人妻妺妺窝人体色www聚色窝 | 日本熟妇丰满大白屁毛片 | 成人国产免费视频 | 免费毛片网 | 麻豆一区二区三区精品视频 | 99久久久国产精品免费99 | 一级片成人 | 色婷婷基地 | 亚洲自拍p | 中文在线√天堂 | av片在线观看免费 | 中文字幕av免费在线观看 | 亚洲欧洲无码av不卡在线 | 少妇性饥渴无码a区免费 | 另类国产ts人妖高潮系列视频 | 日韩三级黄色 | 久久精品国产久精国产一老狼 | 欧洲熟妇色xxxx欧美老妇软件 | 在线免费看黄色 | 欧美日韩二区三区 | 国语对白做受xxxxx在线中国 | 成品人视频ww入口 | 亚洲成在人线aⅴ免费毛片 欧美牲交a欧美牲交aⅴ免费真 | 一级国产片 | 欧美成人免费一级人片100 | 亚洲理论片 | 成人同人动漫免费观看 | 九色av| 国产精品99久久久久久人免费 | h色在线观看| 高h禁伦肉伦np双龙 高h捆绑拘束调教小说 | 国产三级第一页 | 夜夜春亚洲嫩草一区二区 | 男人激烈吮乳吃奶视频片 | 欧美激情国产日韩精品一区18 | 奶大交一乱一乱一视一频 | 大伊人狠狠躁夜夜躁av一区 | 四虎精品成人免费网站 | 热久久伊人 | 少女韩国电视剧在线观看完整 | 色噜噜狠狠一区二区三区 | 在线看成人 | 日日久 | 国产毛片一区二区精品 | 欧美理伦在线观看 | 超碰五月 | 98国产精品综合一区二区三区 | 国产无遮掩 | 国模精品一区 | 中文天堂在线资源 | 中文字幕人妻无码视频 | 欧美视频一区 | 在线观看毛片视频 | 国产免费黄色小视频 | 亚洲小少妇| 日本一区二区不卡在线观看 | 国产精品国产三级国产a | 免费男性肉肉影院 | 黑森林福利视频导航 | 欧美视频免费在线观看 | 韩国久久久久久 | 久久九九日本韩国精品 | 波多野结衣av高清一区二区三区 | 97成人在线观看 | 翘臀后进少妇大白嫩屁股 | 91国自产精品中文字幕亚洲 | 欧美性生交大片免费视频 | 日韩精品成人av | 爱情岛论坛亚洲品质自拍网址大全 | 亚洲福利午夜 | 狠狠躁18三区二区一区 | 风韵丰满熟妇啪啪区老老熟妇 | 欧美一级射 | 91成人免费在线观看 | 国产视频综合 | 成人激情av| 精品在线一区 | 91看片在线观看 | 国产极品美女高潮无套嗷嗷叫酒店 | 国产目拍亚洲精品99久久精品 | 国产精品欧美亚洲 | 丰满少妇女裸体bbw 无码av免费一区二区三区试看 | 7777奶水xxxxx哺乳期 | 中文字幕永久有效 | 天天视频天天爽 | 国产香蕉97碰碰碰视频在线观看 | 毛片手机在线 | 懂色av懂色aⅴ精彩av | 人与禽性视频77777 | 日本黄色片一级 | 无毛av | 中文字幕高潮 | 夜夜摸狠狠添日日添高潮出水 | 传媒一区二区 | 羞羞午夜福利免费视频 | 色www国产亚洲阿娇 色爱av综合 | 男女黄色又爽大片 | 99精品在线视频观看 | 欧美福利一区二区三区 | www夜插内射视频网站 | 亚洲欧美日韩国产综合精品二区 | 欧美11p| 天堂国产永久综合人亚洲欧美 | 国产青青操 | 成人免费观看视频 | 亚洲一卡二卡三卡四卡在线看 | 国产怡春院无码一区二区 | 丰满少妇作爱视频免费观看 | 久久久国产精品入口麻豆 | 亚洲成a人v欧美综合天堂下载 | 成人男同av在线观 | 色情无码一区二区三区 | 国产精品久久久久久久久免费看 | 欧美混交群体交 | 超污网站在线看 | 狠狠色狠狠色合久久伊人 | 日产一二三四五六七区麻豆 |