Java 并發(fā)/多線程教程(四)-并發(fā)模型

? ? ? ? 本系列譯自jakob jenkov的Java并發(fā)多線程教程(本章節(jié)部分內(nèi)容參考http://ifeve.com/并發(fā)編程模型),個(gè)人覺(jué)得很有收獲洼怔。由于個(gè)人水平有限,不對(duì)之處還望矯正罐栈!? ?

? ? ? ? 并發(fā)系統(tǒng)可以有多種并發(fā)模型來(lái)實(shí)現(xiàn)豪嗽,并發(fā)模型指定線程如何協(xié)同完成分配給他們的任務(wù)。不同的并發(fā)模型以不同的方式劃分任務(wù)冕象,并且線程與線程之間以不同的方式進(jìn)行通信和協(xié)作代承。

并發(fā)模型與分布式系統(tǒng)的相似性

? ? ? ? ? 本文中描述的并發(fā)模型類(lèi)似于分布式系統(tǒng)中使用的不同體系結(jié)構(gòu)。在并發(fā)系統(tǒng)中渐扮,不同的線程彼此通信论悴。在分布式系統(tǒng)中,不同的進(jìn)程彼此通信(可能在不同的計(jì)算機(jī)上)墓律。線程和進(jìn)程在本質(zhì)上是非常相似的膀估。這就是為什么不同的并發(fā)模型通常看起來(lái)與不同的分布式系統(tǒng)體系結(jié)構(gòu)相似耻讽。

? ? ? ? 分布式系統(tǒng)在處理網(wǎng)絡(luò)失效察纯、遠(yuǎn)程主機(jī)或進(jìn)程宕掉等方面也面臨著額外的挑戰(zhàn)。但一個(gè)并發(fā)系統(tǒng)運(yùn)行在一個(gè)大型服務(wù)器中有可能也會(huì)遇到類(lèi)似的問(wèn)題,比如一塊 CPU 失效捐寥、一塊網(wǎng)卡失效或一個(gè)磁盤(pán)損壞等情況笤昨。雖然失敗的概率可能較低,但在理論上它仍然可能發(fā)生。

? ? ? ? 由于并發(fā)模型與分布式系統(tǒng)體系結(jié)構(gòu)相似握恳,所以它們常陈髦希可以互相借鑒。例如乡洼,為工作者們(線程)分配作業(yè)的模型一般與分布式系統(tǒng)中的負(fù)載均衡系統(tǒng)比較相似崇裁。同樣,它們?cè)谌罩居涗浭恰⑹мD(zhuǎn)移拔稳、冪等性等錯(cuò)誤處理技術(shù)上也具有相似性。

1锹雏、并行工作者(Parallel worker)

在并行worker模型中巴比,傳入的作業(yè)會(huì)被分配到不同的工作者,下圖展示并行工作者模型

圖片發(fā)自簡(jiǎn)書(shū)App

在并行工作者模型中礁遵,委派者將傳入的作業(yè)分配給不同的工作者轻绞。每個(gè)工作者完成整個(gè)任務(wù),這些工作者并行運(yùn)行在不同的線程上佣耐,甚至可能不在同一個(gè)CPU上政勃。

? ? ? ? 如果在車(chē)廠利用并行工作者模型,那么每一輛車(chē)都是由一工人來(lái)完成的兼砖,這些工人都要有汽車(chē)的生產(chǎn)說(shuō)明書(shū)奸远,并且從頭到尾完成一輛車(chē)的生產(chǎn)。

? ? ? ? 并行工作者并發(fā)模型是Java應(yīng)用中最常用的一種并發(fā)模型(盡管這個(gè)情況在改變)讽挟。在java.util.concurrent包中的很多并發(fā)工具類(lèi)的目的是為了應(yīng)用這個(gè)模型懒叛。在Java企業(yè)版的服務(wù)器應(yīng)用中,也可以看到這個(gè)模型的蹤跡耽梅。

并行工作者模型的優(yōu)點(diǎn)

? ? ? 并行工作者模型的優(yōu)點(diǎn)是他容易理解芍瑞,如果想要增加應(yīng)用的并發(fā)規(guī)模,你只需要添加更多的工作者即可褐墅。

? ? ? 例如:你正在實(shí)現(xiàn)一個(gè)網(wǎng)絡(luò)爬蟲(chóng)拆檬,你可以通過(guò)多個(gè)工作者來(lái)爬一定數(shù)量的頁(yè)面,然后看在一定量的頁(yè)面情況下妥凳,調(diào)整工作者個(gè)數(shù)竟贯,看多少個(gè)工作者用時(shí)最短(意味著高性能),由于網(wǎng)絡(luò)爬蟲(chóng)是一種密集型IO任務(wù)逝钥,所以最終結(jié)果很可能是一個(gè)CPU中可以運(yùn)行多個(gè)爬蟲(chóng)線程屑那。這種情況下拱镐,如果一個(gè)CPU只有一個(gè)爬蟲(chóng)線程將會(huì)浪費(fèi)CPU資源,因?yàn)橄螺d數(shù)據(jù)通常會(huì)產(chǎn)生大量的CPU等待時(shí)間的持际。

并行工作者模型的缺點(diǎn)

? ? ? 并行工作的并發(fā)模型在其簡(jiǎn)單的外表下有一些隱藏缺點(diǎn)沃琅。我將在下面的內(nèi)容中闡述幾個(gè)最明顯的缺點(diǎn)。

A)共享狀態(tài)帶來(lái)了復(fù)雜性

? ? ? 在實(shí)際的的運(yùn)用中蜘欲,并行工作者模型遠(yuǎn)比上面的例子復(fù)雜益眉。共享工作者需要訪問(wèn)一些共享數(shù)據(jù),主些共享數(shù)據(jù)可能是內(nèi)存數(shù)據(jù)或是數(shù)據(jù)庫(kù)數(shù)據(jù)姥份。下面的圖來(lái)展示這樣的情形如何使得并行工作者變得更為復(fù)雜:

? ? ? ? 有時(shí)郭脂,這些共享狀態(tài)可能是通訊機(jī)制里的工作隊(duì)列,有時(shí)可能是業(yè)務(wù)數(shù)據(jù)澈歉,緩存數(shù)據(jù)展鸡,數(shù)據(jù)庫(kù)連接池等。

? ? ? ? 一旦并行工作者模型中有共享狀態(tài)埃难,那么將會(huì)變得很復(fù)雜莹弊,線程訪問(wèn)共享數(shù)據(jù),需要保證共享數(shù)據(jù)如果被一個(gè)線程更改涡尘,要對(duì)其他的線程可見(jiàn)(將修改結(jié)果同步到主存中忍弛,而不是當(dāng)前執(zhí)行線程的CPU緩存中)。線程間需要避免競(jìng)爭(zhēng)悟衩、死鎖和其他的一些因共享狀態(tài)并發(fā)問(wèn)題剧罩。

? ? ? ? 除此之外栓拜,部分并行線程在等待訪問(wèn)共享狀態(tài)時(shí)座泳,許多并發(fā)數(shù)據(jù)結(jié)構(gòu)被阻塞,這就意味著在同一時(shí)刻限制了其他線程對(duì)他們的訪問(wèn)幕与。這將導(dǎo)致線程對(duì)這些共享數(shù)據(jù)結(jié)構(gòu)的競(jìng)爭(zhēng)挑势,從本質(zhì)上講,高競(jìng)爭(zhēng)狀態(tài)會(huì)導(dǎo)致獲取共享數(shù)據(jù)的代碼在一定程度上串行化運(yùn)行啦鸣。

? ? ? ? 現(xiàn)行非阻塞式的并行算法有可能會(huì)減少競(jìng)爭(zhēng)和提高性能潮饱,但是非阻塞式的并行算法很難實(shí)現(xiàn) 。

? ? ? ? 持久化數(shù)據(jù)是另外一種選擇诫给,待久化數(shù)據(jù)結(jié)構(gòu)在修改之前通常會(huì)保存上一個(gè)版本的數(shù)據(jù)香拉,因些,如果多個(gè)線同時(shí)訪問(wèn)持久化數(shù)據(jù)時(shí)中狂,如果其中一個(gè)線程對(duì)數(shù)據(jù)進(jìn)行修改凫碌,修改的線程獲取這個(gè)數(shù)據(jù)結(jié)果的一個(gè)新的引用,而其他線程則保持原有數(shù)據(jù)結(jié)構(gòu)的引用胃榕。Scala語(yǔ)言具有幾種持久化的數(shù)據(jù)結(jié)構(gòu)盛险。

? ? ? 雖然持久化數(shù)據(jù)結(jié)構(gòu)是共享數(shù)據(jù)并發(fā)讀寫(xiě)中遇到的問(wèn)題的一個(gè)看似“優(yōu)雅的”解決方案,但其性能并不那么好。

? ? ? 例如:一個(gè)待久化的列表苦掘,添加一些新的元素到這個(gè)列表的頭部换帜,然后返回新加元素的引用。其他的線程仍舊保持持久化列表之前的引用鹤啡,因此對(duì)這些線程來(lái)說(shuō)惯驼,新添加的元素對(duì)他們是不可見(jiàn)的。

B)無(wú)狀態(tài)的工作者

? ? ? ? 由于共享狀態(tài)可能被系統(tǒng)中的其他線程修改揉忘。所以工作者在需要用到的時(shí)候必須重新去讀取這個(gè)狀態(tài)跳座,以確保當(dāng)前工作者運(yùn)行在最新的副本上。不管這個(gè)狀態(tài)是保存于內(nèi)存中泣矛,還是保存在外部的數(shù)據(jù)庫(kù)中疲眷,都是這樣去實(shí)現(xiàn)的。一個(gè)工作者您朽,不需要在線程內(nèi)部保存狀態(tài)(而是在需要用到的時(shí)候重新去讀瓤袼俊),這樣就稱(chēng)之為無(wú)狀態(tài)哗总。

? ? ? 每次重新去獲取共享數(shù)據(jù)的狀態(tài)會(huì)變慢几颜,尤其是共享狀態(tài)存儲(chǔ)在外部的數(shù)據(jù)庫(kù)中。

C) 工作順序是不確定的

? ? ? 并行工作者的另一個(gè)缺點(diǎn)就是工作順序的不確定讯屈。我們沒(méi)有辦法去保證任務(wù)按順序執(zhí)行蛋哭,例如:任務(wù)A有可能在任務(wù)B之前執(zhí)行,也有可能任務(wù)B先于任務(wù)A執(zhí)行涮母。

? ? ? 并于工作者模型的順序不確定性使得我們很難確定在給定的某個(gè)時(shí)間的狀態(tài)谆趾。并且也很難保證一個(gè)任務(wù)發(fā)生于另一個(gè)任務(wù)之前 。

2叛本、流水線模型

? ? ? ? 第二種并發(fā)模型稱(chēng)之為流水線模型沪蓬。我之所以取這個(gè)名字,只是為了配合“并行工作模型”来候。其他的程序員跷叉,可能會(huì)用其他名字。下圖表示一個(gè)流水線模型营搅。

? ? ? ? 像工作生產(chǎn)線上的工人們一樣組織工作者云挟,每個(gè)工作者只負(fù)責(zé)整個(gè)任務(wù)中的一部分,當(dāng)完成自己這部分的工作的工作者會(huì)將任務(wù)轉(zhuǎn)發(fā)給下一個(gè)工作者转质。每個(gè)工作者都在自己的線程中運(yùn)行园欣,并且不會(huì)和其他 的工作者共享狀態(tài)。因此有時(shí)也稱(chēng)之為無(wú)共享并行模型峭拘。

? ? ? ? 通常使用非阻塞的IO來(lái)設(shè)計(jì)使用流水線并發(fā)模型的系統(tǒng)俊庇。非阻塞意味著當(dāng)一個(gè)工作者操作IO時(shí)(比如:讀取文件或是從網(wǎng)絡(luò)連接中獲取數(shù)據(jù)),工作者不需要等到IO操作結(jié)束狮暑,由于IO操作非常慢,因此等待IO操作完成很浪費(fèi)CPU時(shí)間辉饱,在等待IO操作完成的同時(shí)搬男,CPU可以做些其他的事情,當(dāng)IO操作完成時(shí)彭沼,被傳遞給下一個(gè)工作者缔逛。

? ? ? ? 有了非阻塞IO,就可以使用IO操作來(lái)確定工作者之間的邊界姓惑。工作者會(huì)盡可能多的運(yùn)行直到遇到并啟動(dòng)一個(gè)IO操作褐奴。然后交出工作的控制權(quán),當(dāng)IO操作完成后于毙。然后在流水線上的下一個(gè)工作者繼續(xù)進(jìn)行操作敦冬。直到他也遇到并啟動(dòng)一個(gè)IO操作。

? ? ? 實(shí)事上唯沮,作業(yè)不可能沿著單一的流水線脖旱,由于多數(shù)的系統(tǒng)可能執(zhí)行多個(gè)作業(yè)。作業(yè)從一個(gè)工作者流向另一個(gè)工作者取決于作業(yè)需要做的工作介蛉。在實(shí)際中可能會(huì)有多個(gè)不同的虛擬流水線同時(shí)運(yùn)行萌庆。下面是現(xiàn)實(shí)中作業(yè)在流水線系統(tǒng)中可能的情況:

? ? ? ? 作業(yè)可能被轉(zhuǎn)發(fā)到多個(gè)工作者上并發(fā)處理。比如:作業(yè)可能同時(shí)被轉(zhuǎn)發(fā)到任務(wù)執(zhí)行器和作業(yè)日志币旧。下圖說(shuō)明了三條流水線是如何把一個(gè)作業(yè)轉(zhuǎn)發(fā)給同一個(gè)工作者(中間流水線的最后一個(gè)工作者)來(lái)完成作業(yè):

? ? ? ? 流水線作業(yè)有時(shí)會(huì)比這個(gè)更復(fù)雜

響應(yīng)(Reactive)践险,事件驅(qū)動(dòng)

? ? ? 采用流水線并發(fā)模型的系統(tǒng)有時(shí)也稱(chēng)之為Reactive或是事件驅(qū)動(dòng)系統(tǒng)。系統(tǒng)中的工作者會(huì)對(duì)來(lái)自系統(tǒng)內(nèi)部的事件吹菱,或者接受外部的請(qǐng)求或者其他工作傳入的事件做出響應(yīng)巍虫。舉個(gè)例子:事件有可能是來(lái)自于外部的HTTP請(qǐng)求,也有可能是某個(gè)文件成功加載到內(nèi)存中毁葱。

Actors vs. Channels

? ? ? Actors和Channels是兩種比較類(lèi)似的流水線(Reactive/事件驅(qū)動(dòng))模型垫言。在Actor模型中每個(gè)工作者被稱(chēng)之為actor贰剥,Actor之間可以異步發(fā)送和處理消息倾剿。actor可以被用來(lái)實(shí)現(xiàn)一個(gè)或多個(gè)流水線作業(yè)。下圖給出了actor模型的:

? ? ? 而在channel模型中蚌成。工作者之間不直接與其他工作者通信前痘。而是他們把他們的消息(事件)發(fā)布到另一個(gè)不同的channel,其他工作者可以監(jiān)聽(tīng)在這個(gè)channel上担忧,而發(fā)布者不需要知道是誰(shuí)在監(jiān)聽(tīng)芹缔。下圖給出了channel模型:


? ? ? 在寫(xiě)這篇文章的時(shí)候,channel模型對(duì)于我來(lái)說(shuō)似乎更加靈活瓶盛。一個(gè)工作者無(wú)需知道誰(shuí)在后面的流水線上處理作業(yè)最欠。只需知道作業(yè)(或消息等)需要轉(zhuǎn)發(fā)給哪個(gè)通道示罗。通道上的監(jiān)聽(tīng)者可以隨意訂閱或者取消訂閱,并不會(huì)影響向這個(gè)通道發(fā)送消息的工作者芝硬。這使得工作者之間具有松散的耦合蚜点。

流水線模型的優(yōu)點(diǎn)

? ? ? 相對(duì)于并行工作者模型,流水線模型具有幾個(gè)優(yōu)點(diǎn)拌阴,在接下來(lái)的章節(jié)中我會(huì)介紹幾個(gè)最大的優(yōu)點(diǎn)绍绘。

無(wú)共享狀態(tài)

? ? ? 工作者之間無(wú)狀態(tài)。意味著實(shí)現(xiàn)的時(shí)候無(wú)需考慮所有因并發(fā)訪問(wèn)共享對(duì)象而產(chǎn)生的并發(fā)性問(wèn)題迟赃。這使得在實(shí)現(xiàn)工作者的時(shí)候變得非常容易陪拘。在實(shí)現(xiàn)工作的時(shí)候就好像是單個(gè)線程在處理工作一樣,這基本上是一個(gè)單線程的實(shí)現(xiàn) 纤壁。

有狀態(tài)的工作者

? ? ? ? 當(dāng)工作者知道沒(méi)有別的線程修改它們的數(shù)據(jù)左刽,工作者可以是有狀態(tài)的,對(duì)于有狀態(tài)酌媒,我的意思是悠反,它們可以在內(nèi)存中保存要操作的數(shù)據(jù),只需要在最后把更改的結(jié)果寫(xiě)回到外部存儲(chǔ)系統(tǒng)馍佑。因此斋否,有狀態(tài)的工作者通常比無(wú)狀態(tài)的工作者更快。

更好的與硬件結(jié)合

? ? ? ? 單線程代碼通常在結(jié)合底層硬件時(shí)具有更好的優(yōu)勢(shì)拭荤。首先茵臭,當(dāng)你假設(shè)代碼只在單線程模型下運(yùn)行時(shí),通常能能創(chuàng)建更優(yōu)的數(shù)據(jù)結(jié)構(gòu)和算法 舅世。

? ? ? 其次旦委,單線程的工作者可以緩存數(shù)據(jù)到內(nèi)存中,當(dāng)數(shù)據(jù)緩存在內(nèi)存中雏亚,有很大的可能數(shù)據(jù)也緩存在執(zhí)行這個(gè)線程的CPU中缨硝,這使得訪問(wèn)緩存數(shù)據(jù)變得很快。

合理的作業(yè)順序

? ? ? 基于流水線并發(fā)模型實(shí)現(xiàn)的并發(fā)系統(tǒng)罢低,在某種程度上是有可能保證作業(yè)的順序的查辩。作業(yè)的有序性使得它更容易地推出系統(tǒng)在某個(gè)特定時(shí)間點(diǎn)的狀態(tài)。更進(jìn)一步网持,你可以將所有到達(dá)的作業(yè)寫(xiě)入到日志中去宜岛。一旦這個(gè)系統(tǒng)的某一部分掛掉了,該日志就可以用來(lái)重頭開(kāi)始重建系統(tǒng)當(dāng)時(shí)的狀態(tài)功舀。按照特定的順序?qū)⒆鳂I(yè)寫(xiě)入日志萍倡,并按這個(gè)順序作為有保障的作業(yè)順序。下圖展示了一種可能的設(shè)計(jì):

? ? ? 實(shí)現(xiàn)一個(gè)有保障的作業(yè)順序是不容易的辟汰,但往往是可行的列敲。如果可以阱佛,它 將大大簡(jiǎn)化一些任務(wù),例如備份戴而、數(shù)據(jù)恢復(fù)瘫絮、數(shù)據(jù)復(fù)制等,這些都可以通過(guò)日志文件來(lái)完成填硕。

流水線模型的缺點(diǎn)

? ? ? 流水線并發(fā)模型最大的缺點(diǎn)是作業(yè)的執(zhí)行往往分布到多個(gè)工作者上麦萤,并因此分布到項(xiàng)目中的多個(gè)類(lèi)上。這樣導(dǎo)致在追蹤某個(gè)作業(yè)到底被什么代碼執(zhí)行時(shí)變得困難扁眯。

? ? ? ? 流水線并發(fā)模型最大的缺點(diǎn)是作業(yè)的執(zhí)行往往分布到多個(gè)工作者上壮莹,并因此分布到項(xiàng)目中的多個(gè)類(lèi)上。這樣導(dǎo)致在追蹤某個(gè)作業(yè)到底被什么代碼執(zhí)行時(shí)變得困難姻檀。

? ? ? 使用并行工作者模型可以簡(jiǎn)化這個(gè)問(wèn)題命满。你可以打開(kāi)工作者的代碼,從頭到尾優(yōu)美的閱讀被執(zhí)行的代碼绣版。當(dāng)然并行工作者模式的代碼也可能同樣分布在不同的類(lèi)中胶台,但往往也能夠很容易的從代碼中分析執(zhí)行的順序。

3杂抽、函數(shù)式并行(Functional Parallelism)

? ? ? 第三種并發(fā)模型是函數(shù)式并行模型诈唬。函數(shù)式并行的基本思想是采用函數(shù)調(diào)用實(shí)現(xiàn)程序。函數(shù)可以看作是”代理人(agents)“或者”actor“缩麸,函數(shù)之間可以像流水線模型(AKA 反應(yīng)器或者事件驅(qū)動(dòng)系統(tǒng))那樣互相發(fā)送消息铸磅。某個(gè)函數(shù)調(diào)用另一個(gè)函數(shù),這個(gè)過(guò)程類(lèi)似于消息發(fā)送杭朱。

? ? ? 函數(shù)都是通過(guò)拷貝來(lái)傳遞參數(shù)的阅仔,所以除了接收函數(shù)外沒(méi)有實(shí)體可以操作數(shù)據(jù)。這對(duì)于避免共享數(shù)據(jù)的競(jìng)態(tài)來(lái)說(shuō)是很有必要的弧械。同樣也使得函數(shù)的執(zhí)行類(lèi)似于原子操作八酒。每個(gè)函數(shù)調(diào)用的執(zhí)行獨(dú)立于任何其他函數(shù)的調(diào)用。

? ? ? ? 一旦每個(gè)函數(shù)調(diào)用都可以獨(dú)立的執(zhí)行刃唐,它們就可以分散在不同的CPU上執(zhí)行了羞迷。這也就意味著能夠在多處理器上并行的執(zhí)行使用函數(shù)式實(shí)現(xiàn)的算法。

? ? ? ? Java7中的java.util.concurrent包里包含的ForkAndJoinPool能夠幫助我們實(shí)現(xiàn)類(lèi)似于函數(shù)式并行的一些東西唁桩。而Java8中并行streams能夠用來(lái)幫助我們并行的迭代大型集合闭树。

? ? ? 函數(shù)式并行里面最難的是確定需要并行的那個(gè)函數(shù)調(diào)用耸棒』脑瑁跨CPU協(xié)調(diào)函數(shù)調(diào)用需要一定的開(kāi)銷(xiāo)。某個(gè)函數(shù)完成的工作單元需要達(dá)到某個(gè)大小以彌補(bǔ)這個(gè)開(kāi)銷(xiāo)与殃。如果函數(shù)調(diào)用作用非常小单山,將它并行化可能比單線程碍现、單CPU執(zhí)行還慢。

? ? ? ? 我個(gè)人認(rèn)為(可能不太正確)米奸,你可以使用響應(yīng)模型(Reactive)或者事件驅(qū)動(dòng)模型實(shí)現(xiàn)一個(gè)算法昼接,像函數(shù)式并行那樣的方法實(shí)現(xiàn)工作的分解。使用事件驅(qū)動(dòng)模型可以更精確的控制如何實(shí)現(xiàn)并行化(我的觀點(diǎn))悴晰。

? ? ? ? 此外慢睡,將任務(wù)拆分給多個(gè)CPU時(shí)協(xié)調(diào)造成的開(kāi)銷(xiāo),僅僅在該任務(wù)是程序當(dāng)前執(zhí)行的唯一任務(wù)時(shí)才有意義铡溪。但是漂辐,如果當(dāng)前系統(tǒng)正在執(zhí)行多個(gè)其他的任務(wù)時(shí)(比如web服務(wù)器,數(shù)據(jù)庫(kù)服務(wù)器或者很多其他類(lèi)似的系統(tǒng))棕硫,將單個(gè)任務(wù)進(jìn)行并行化是沒(méi)有意義的髓涯。不管怎樣計(jì)算機(jī)中的其他CPU們都在忙于處理其他任務(wù),沒(méi)有理由用一個(gè)慢的哈扮、函數(shù)式并行的任務(wù)去擾亂它們纬纪。使用流水線(反應(yīng)器)并發(fā)模型可能會(huì)更好一點(diǎn),因?yàn)樗_(kāi)銷(xiāo)更谢狻(在單線程模式下順序執(zhí)行)同時(shí)能更好的與底層硬件整合包各。

使用那種并發(fā)模型最好?

? ? ? ? 所以靶庙,用哪種并發(fā)模型更好呢?

? ? ? ? 通常情況下髓棋,這個(gè)答案取決于你的系統(tǒng)打算做什么。如果你的作業(yè)本身就是并行的惶洲、獨(dú)立的并且沒(méi)有必要共享狀態(tài)按声,你可能會(huì)使用并行工作者模型去實(shí)現(xiàn)你的系統(tǒng)。雖然許多作業(yè)都不是自然并行和獨(dú)立的恬吕。對(duì)于這種類(lèi)型的系統(tǒng)签则,我相信使用流水線并發(fā)模型能夠更好的發(fā)揮它的優(yōu)勢(shì),而且比并行工作者模型更有優(yōu)勢(shì)铐料。

? ? ? ? 你甚至不用親自編寫(xiě)所有流水線模型的基礎(chǔ)結(jié)構(gòu)渐裂。像Vert.x這種現(xiàn)代化的平臺(tái)已經(jīng)為你實(shí)現(xiàn)了很多。我也會(huì)去為探索如何設(shè)計(jì)我的下一個(gè)項(xiàng)目钠惩,使它運(yùn)行在像Vert.x這樣的優(yōu)秀平臺(tái)上柒凉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市篓跛,隨后出現(xiàn)的幾起案子膝捞,更是在濱河造成了極大的恐慌,老刑警劉巖愧沟,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔬咬,死亡現(xiàn)場(chǎng)離奇詭異鲤遥,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)林艘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)盖奈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人狐援,你說(shuō)我怎么就攤上這事钢坦。” “怎么了啥酱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵场钉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我懈涛,道長(zhǎng)逛万,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任批钠,我火速辦了婚禮宇植,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘埋心。我一直安慰自己指郁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布拷呆。 她就那樣靜靜地躺著闲坎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪茬斧。 梳的紋絲不亂的頭發(fā)上腰懂,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音项秉,去河邊找鬼绣溜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛娄蔼,可吹牛的內(nèi)容都是我干的怖喻。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼岁诉,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼锚沸!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起涕癣,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤哗蜈,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體恬叹,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡候生,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年同眯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绽昼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡须蜗,死狀恐怖硅确,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情明肮,我是刑警寧澤菱农,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站柿估,受9級(jí)特大地震影響循未,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秫舌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一的妖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧足陨,春花似錦嫂粟、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至镊讼,卻和暖如春宽涌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蝶棋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工护糖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嚼松。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓嫡良,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親献酗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子寝受,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 漸漸地不再鼓勵(lì)自己, 漸漸地接納恐懼罕偎, 繼而很澄,與怯懦握手言和~ 孤夜里,終究疲于自欺。 憤怒甩苛,哀傷蹂楣,妒忌…… 和它...
    我想與字談情閱讀 484評(píng)論 0 0
  • 我一直以為來(lái)到這座城市有十年了,2009年九月的某個(gè)紅眼航班落地至今讯蒲,怎么算也不過(guò)才九年. 還清晰的記...
    夏曉柒July閱讀 200評(píng)論 0 0