溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Fork跟Join原理是什么

發(fā)布時(shí)間:2021-09-17 13:50:10 來(lái)源:億速云 閱讀:98 作者:柒染 欄目:web開(kāi)發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)Fork跟Join原理是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

Fork跟Join原理是什么

只聽(tīng)到P8大佬不急不慢問(wèn)道:談?wù)剬?duì)JDK并發(fā)工具的認(rèn)識(shí)?

我開(kāi)始仔細(xì)梳理多年的并發(fā)八股文經(jīng)驗(yàn),道:

線(xiàn)程池、Future、CompletableFuture和CompletionService這些并發(fā)工具都是幫助SE站在任務(wù)角度解決并發(fā)問(wèn)題,而非糾結(jié)于線(xiàn)程之間協(xié)作的細(xì)節(jié),比如線(xiàn)程之間如何實(shí)現(xiàn)等待、通知。

  • 簡(jiǎn)單并行任務(wù)

線(xiàn)程池+Future 組合拳

  • 任務(wù)間有聚合關(guān)系

AND、OR聚合,CompletableFuture 一招鮮

  • 批量的并行任務(wù)

CompletionService 一把梭

并發(fā)編程可分為三個(gè)層面問(wèn)題:分工、協(xié)作、互斥。

當(dāng)關(guān)注于任務(wù)時(shí),你會(huì)發(fā)現(xiàn)你的視角已躍出并發(fā)編程細(xì)節(jié),而使用現(xiàn)實(shí)世界思維模式,類(lèi)比現(xiàn)實(shí)世界的分工,其實(shí)線(xiàn)程池、Future、CompletableFuture和CompletionService都可列為分工問(wèn)題。

  • 簡(jiǎn)單并行任務(wù)、聚合任務(wù)和批量并行任務(wù)的現(xiàn)實(shí)的工作流程圖

Fork跟Join原理是什么

這三種任務(wù)模型,基本覆蓋日常工作中的并發(fā)場(chǎng)景,但其實(shí)還有一種“分治”任務(wù)模型。

分治,分而治之,一種解決復(fù)雜問(wèn)題的思維方法和模式。把一個(gè)復(fù)雜問(wèn)題分解成多個(gè)相似的子問(wèn)題,然后再把子問(wèn)題分解成更小的子問(wèn)題,直到子問(wèn)題簡(jiǎn)單到可以直接求解。理論上解決每一個(gè)問(wèn)題都對(duì)應(yīng)著一個(gè)任務(wù),所以對(duì)于問(wèn)題的分治,實(shí)際上就是對(duì)于任務(wù)的分治。

P8 大佬直接開(kāi)問(wèn),那你說(shuō)說(shuō)什么是分治任務(wù)模型?

分治任務(wù)模型可分為兩個(gè)階段:

  • 任務(wù)分解

將任務(wù)迭代地分解為子任務(wù),直至子任務(wù)可計(jì)算出結(jié)果。將地區(qū)具體事務(wù)分屬各個(gè)地方行政官。

  • 結(jié)果合并

逐層合并子任務(wù)的執(zhí)行結(jié)果,直至獲得最終結(jié)果。各地方行政官最終將治理成果匯報(bào)上級(jí)。

就像官僚制度一樣:

Fork跟Join原理是什么

那你平時(shí)開(kāi)發(fā)是如何使用Fork/Join的?

我,我平時(shí)還真沒(méi)通過(guò)啊,就背過(guò)。還好這道題,我面試前也準(zhǔn)備了…

Fork/Join是一個(gè)并行計(jì)算框架,以支持分治任務(wù)模型

  • Fork對(duì)應(yīng)分治任務(wù)模型里的任務(wù)分解

  • Join對(duì)應(yīng)結(jié)果合并

Fork/Join計(jì)算框架主要包含兩部分:

  • 分治任務(wù)的線(xiàn)程池ForkJoinPool

  • 分治任務(wù)ForkJoinTask

這倆的關(guān)系類(lèi)似于 ThreadPoolExecutor 和  Runnable,都是提交任務(wù)到線(xiàn)程池,只不過(guò)分治任務(wù)有自己獨(dú)特的任務(wù)類(lèi)型ForkJoinTask。

ForkJoinTask

JDK7 提供,一個(gè)抽象類(lèi),核心方法如下:

  • fork()

異步執(zhí)行一個(gè)子任務(wù)

  • join()

阻塞當(dāng)前線(xiàn)程來(lái)等待子任務(wù)的執(zhí)行結(jié)果

ForkJoinTask有兩個(gè)子類(lèi)——RecursiveAction和RecursiveTask,顯然都是用遞歸處理分治任務(wù)。這兩個(gè)子類(lèi)都定義了抽象方法compute():

  • RecursiveAction#compute()無(wú)返回值

Fork跟Join原理是什么

  • RecursiveTask#compute()有返回值

Fork跟Join原理是什么

注意到這倆類(lèi)都是抽象類(lèi),使用要定義子類(lèi)實(shí)現(xiàn)。

Fork跟Join原理是什么

只見(jiàn) P8 開(kāi)始冷笑,看來(lái)要問(wèn)源碼級(jí)別原理了!

那你說(shuō)下Fork/Join的工作原理

還好我知道阿里面試套路,凡是 java 工具,必問(wèn)深入的源碼。

因?yàn)镕ork/Join的核心就是ForkJoinPool,讓我來(lái)深入講解ForkJoinPool原理。

ThreadPoolExecutor本質(zhì)是個(gè)生產(chǎn)者-消費(fèi)者實(shí)現(xiàn),內(nèi)部有一個(gè)任務(wù)隊(duì)列,作為生產(chǎn)者和消費(fèi)者的通信媒介。ThreadPoolExecutor可以有多個(gè)工作線(xiàn)程,這些工作線(xiàn)程都共享一個(gè)任務(wù)隊(duì)列。

ForkJoinPool本質(zhì)上也是一個(gè)生產(chǎn)者-消費(fèi)者的實(shí)現(xiàn),但更智能

  • ForkJoinPool工作原理圖

Fork跟Join原理是什么

ThreadPoolExecutor內(nèi)部只有一個(gè)任務(wù)隊(duì)列,而ForkJoinPool內(nèi)部有多個(gè)任務(wù)隊(duì)列,當(dāng)調(diào)用ForkJoinPool#invoke()或submit()提交任務(wù)時(shí),F(xiàn)orkJoinPool把任務(wù)通過(guò)路由規(guī)則提交到一個(gè)任務(wù)隊(duì)列,如果任務(wù)在執(zhí)行過(guò)程中會(huì)創(chuàng)建出子任務(wù),那么子任務(wù)會(huì)提交到工作線(xiàn)程對(duì)應(yīng)的任務(wù)隊(duì)列。

如果工作線(xiàn)程對(duì)應(yīng)的任務(wù)隊(duì)列空,是不是就沒(méi)活兒干了?

No!ForkJoinPool有個(gè)“任務(wù)竊取”機(jī)制,若工作線(xiàn)程空閑了,它會(huì)“竊取”其他工作任務(wù)隊(duì)列里的任務(wù),例如剛才那個(gè)圖中,線(xiàn)程T2對(duì)應(yīng)任務(wù)隊(duì)列已空

那它會(huì)“竊取”線(xiàn)程T1對(duì)應(yīng)的任務(wù)隊(duì)列的任務(wù)。這樣所有工作線(xiàn)程都不會(huì)閑著。

ForkJoinPool的任務(wù)隊(duì)列采用的是雙端隊(duì)列,工作線(xiàn)程正常獲取任務(wù)和“竊取任務(wù)”分別從任務(wù)隊(duì)列不同的端消費(fèi),這也能避免很多不必要的數(shù)據(jù)競(jìng)爭(zhēng)。

ForkJoinPool支持任務(wù)竊取機(jī)制,能夠讓所有線(xiàn)程的工作量基本公平,不會(huì)出現(xiàn)線(xiàn)程有的很忙,有的一直在摸魚(yú),所以性能很好,是個(gè)很公正的領(lǐng)導(dǎo)。

Java8的Stream API里面并行流也是基于ForkJoinPool。

默認(rèn),所有的并行流計(jì)算都共享一個(gè)ForkJoinPool,這個(gè)共享的ForkJoinPool的默認(rèn)線(xiàn)程數(shù)是CPU核數(shù);

若所有并行流計(jì)算都是CPU密集型,完全沒(méi)有問(wèn)題,但若存在I/O密集型并行流計(jì)算,那很可能因?yàn)橐粋€(gè)很慢的I/O計(jì)算而拖慢整個(gè)系統(tǒng)的性能。所以建議用不同F(xiàn)orkJoinPool執(zhí)行不同類(lèi)型的計(jì)算任務(wù)。

關(guān)于Fork跟Join原理是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI