自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

和阿里P8大佬面試互懟了半小時(shí)的Fork/Join原理

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

[[396065]]

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

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

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

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

線程池+Future 組合拳

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

AND、OR聚合,CompletableFuture 一招鮮

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

CompletionService 一把梭

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

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

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

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

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

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

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

  • 任務(wù)分解

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

  • 結(jié)果合并

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

就像官僚制度一樣:

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

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

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

  • Fork對(duì)應(yīng)分治任務(wù)模型里的任務(wù)分解
  • Join對(duì)應(yīng)結(jié)果合并

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

  • 分治任務(wù)的線程池ForkJoinPool
  • 分治任務(wù)ForkJoinTask

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

ForkJoinTask

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

  • fork()

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

  • join()

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

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

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

  • RecursiveTask#compute()有返回值

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

只見 P8 開始冷笑,看來(lái)要問源碼級(jí)別原理了!

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

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

因?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è)工作線程,這些工作線程都共享一個(gè)任務(wù)隊(duì)列。

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

  • ForkJoinPool工作原理圖

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ì)提交到工作線程對(duì)應(yīng)的任務(wù)隊(duì)列。

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

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

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

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

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

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

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

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

參考

https://www.liaoxuefeng.com/article/1146802219354112

本文轉(zhuǎn)載自微信公眾號(hào)「JavaEdge」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系JavaEdge公眾號(hào)。

 

 

責(zé)任編輯:武曉燕 來(lái)源: JavaEdge
相關(guān)推薦

2020-03-23 08:02:37

阿里工程師能力

2021-09-30 11:58:05

阿里P8雨水

2022-02-16 16:36:55

阿里面試面試流程背景

2021-01-18 08:40:41

年薪阿里團(tuán)隊(duì)

2021-09-13 08:38:42

阿里時(shí)間成本

2021-08-20 10:53:21

技術(shù)阿里P8

2021-06-07 08:26:35

P8員工公司

2020-01-21 09:51:32

結(jié)構(gòu)化思維互聯(lián)網(wǎng)

2020-10-26 11:41:47

kill代碼

2018-08-28 16:22:57

數(shù)據(jù)庫(kù)NoSQLSQL

2011-12-27 10:17:56

JDKJava

2017-08-04 11:41:53

Javathreadpool框架

2017-08-07 20:50:27

JavaForkJoin

2019-02-26 12:40:10

程序員架構(gòu)師阿里

2013-04-01 10:04:46

2020-04-14 10:44:16

阿里安全白帽子

2018-08-07 10:04:11

數(shù)據(jù)庫(kù)分布式緩存Redis

2016-09-23 18:37:06

云計(jì)算騰訊云百度云

2019-10-22 18:00:00

MySQL基礎(chǔ)入門數(shù)據(jù)庫(kù)

2013-03-21 10:03:04

Perl
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)