中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Fork跟Join原理是什么

發布時間:2021-09-17 13:50:10 來源:億速云 閱讀:101 作者:柒染 欄目:web開發

這篇文章將為大家詳細講解有關Fork跟Join原理是什么,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

Fork跟Join原理是什么

只聽到P8大佬不急不慢問道:談談對JDK并發工具的認識?

我開始仔細梳理多年的并發八股文經驗,道:

線程池、Future、CompletableFuture和CompletionService這些并發工具都是幫助SE站在任務角度解決并發問題,而非糾結于線程之間協作的細節,比如線程之間如何實現等待、通知。

  • 簡單并行任務

線程池+Future 組合拳

  • 任務間有聚合關系

AND、OR聚合,CompletableFuture 一招鮮

  • 批量的并行任務

CompletionService 一把梭

并發編程可分為三個層面問題:分工、協作、互斥。

當關注于任務時,你會發現你的視角已躍出并發編程細節,而使用現實世界思維模式,類比現實世界的分工,其實線程池、Future、CompletableFuture和CompletionService都可列為分工問題。

  • 簡單并行任務、聚合任務和批量并行任務的現實的工作流程圖

Fork跟Join原理是什么

這三種任務模型,基本覆蓋日常工作中的并發場景,但其實還有一種“分治”任務模型。

分治,分而治之,一種解決復雜問題的思維方法和模式。把一個復雜問題分解成多個相似的子問題,然后再把子問題分解成更小的子問題,直到子問題簡單到可以直接求解。理論上解決每一個問題都對應著一個任務,所以對于問題的分治,實際上就是對于任務的分治。

P8 大佬直接開問,那你說說什么是分治任務模型?

分治任務模型可分為兩個階段:

  • 任務分解

將任務迭代地分解為子任務,直至子任務可計算出結果。將地區具體事務分屬各個地方行政官。

  • 結果合并

逐層合并子任務的執行結果,直至獲得最終結果。各地方行政官最終將治理成果匯報上級。

就像官僚制度一樣:

Fork跟Join原理是什么

那你平時開發是如何使用Fork/Join的?

我,我平時還真沒通過啊,就背過。還好這道題,我面試前也準備了…

Fork/Join是一個并行計算框架,以支持分治任務模型

  • Fork對應分治任務模型里的任務分解

  • Join對應結果合并

Fork/Join計算框架主要包含兩部分:

  • 分治任務的線程池ForkJoinPool

  • 分治任務ForkJoinTask

這倆的關系類似于 ThreadPoolExecutor 和  Runnable,都是提交任務到線程池,只不過分治任務有自己獨特的任務類型ForkJoinTask。

ForkJoinTask

JDK7 提供,一個抽象類,核心方法如下:

  • fork()

異步執行一個子任務

  • join()

阻塞當前線程來等待子任務的執行結果

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

  • RecursiveAction#compute()無返回值

Fork跟Join原理是什么

  • RecursiveTask#compute()有返回值

Fork跟Join原理是什么

注意到這倆類都是抽象類,使用要定義子類實現。

Fork跟Join原理是什么

只見 P8 開始冷笑,看來要問源碼級別原理了!

那你說下Fork/Join的工作原理

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

因為Fork/Join的核心就是ForkJoinPool,讓我來深入講解ForkJoinPool原理。

ThreadPoolExecutor本質是個生產者-消費者實現,內部有一個任務隊列,作為生產者和消費者的通信媒介。ThreadPoolExecutor可以有多個工作線程,這些工作線程都共享一個任務隊列。

ForkJoinPool本質上也是一個生產者-消費者的實現,但更智能

  • ForkJoinPool工作原理圖

Fork跟Join原理是什么

ThreadPoolExecutor內部只有一個任務隊列,而ForkJoinPool內部有多個任務隊列,當調用ForkJoinPool#invoke()或submit()提交任務時,ForkJoinPool把任務通過路由規則提交到一個任務隊列,如果任務在執行過程中會創建出子任務,那么子任務會提交到工作線程對應的任務隊列。

如果工作線程對應的任務隊列空,是不是就沒活兒干了?

No!ForkJoinPool有個“任務竊取”機制,若工作線程空閑了,它會“竊取”其他工作任務隊列里的任務,例如剛才那個圖中,線程T2對應任務隊列已空

那它會“竊取”線程T1對應的任務隊列的任務。這樣所有工作線程都不會閑著。

ForkJoinPool的任務隊列采用的是雙端隊列,工作線程正常獲取任務和“竊取任務”分別從任務隊列不同的端消費,這也能避免很多不必要的數據競爭。

ForkJoinPool支持任務竊取機制,能夠讓所有線程的工作量基本公平,不會出現線程有的很忙,有的一直在摸魚,所以性能很好,是個很公正的領導。

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

默認,所有的并行流計算都共享一個ForkJoinPool,這個共享的ForkJoinPool的默認線程數是CPU核數;

若所有并行流計算都是CPU密集型,完全沒有問題,但若存在I/O密集型并行流計算,那很可能因為一個很慢的I/O計算而拖慢整個系統的性能。所以建議用不同ForkJoinPool執行不同類型的計算任務。

關于Fork跟Join原理是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

抚松县| 南昌县| 舞阳县| 牟定县| 江津市| 农安县| 靖宇县| 东阳市| 肇庆市| 本溪| 马鞍山市| 朝阳市| 上杭县| 阿尔山市| 鄂托克前旗| 东丽区| 茂名市| 通渭县| 水城县| 三亚市| 安图县| 镇雄县| 太仓市| 且末县| 永登县| 定西市| 武义县| 庆阳市| 海丰县| 玉屏| 田东县| 乌拉特前旗| 疏附县| 鲁山县| 鄂托克前旗| 祁连县| 泊头市| 武汉市| 宜川县| 阜平县| 武威市|