JDK中的Future異步編程模式

本節(jié)內(nèi)容摘自《Java異步編程實(shí)戰(zhàn)》中的一小節(jié)匆绣。

前言

本篇主要講解如何使用JDK中的Future 實(shí)現(xiàn)異步編程,包括如何使用FutureTask 實(shí)現(xiàn)異步編程以及內(nèi)部實(shí)現(xiàn)原理以及FutureTask 的局限性崎淳。

JDK 中的Future

在Java并發(fā)包(JUC包)中Future 代表著異步計(jì)算的結(jié)果,F(xiàn)uture中提供了一些方法用來檢查計(jì)算結(jié)果的完成,還提供了同步等待任務(wù)執(zhí)行完成的方法森爽,以及獲取結(jié)果的方法。當(dāng)計(jì)算結(jié)果完成時爬迟,通過提供的get系列方法來獲取結(jié)果橘蜜,如果使用了不帶超時時間的方法來獲取結(jié)果付呕,則在計(jì)算結(jié)果完成前,調(diào)用線程會一直阻塞徽职,另外計(jì)算任務(wù)是可以通過cancel 方法來取消的象颖,前提就是任務(wù)未執(zhí)行完畢姆钉。

首先我們來看下Future 接口的結(jié)構(gòu)圖

1.png
V get() throws InterruptedException, ExecutionException;

等待異步計(jì)算任務(wù)完成并返回結(jié)果;如果任務(wù)未執(zhí)行完畢潮瓶,則一直阻塞等待任務(wù)的完成。

CancellationException:如果計(jì)算任務(wù)被取消 拋出次異常

ExecutionException:如果任務(wù)執(zhí)行中出現(xiàn)了異常

InterruptedException:如果等待結(jié)果線程被其他線程打斷

V get(long timeout, TimeUnit unit)
   throws InterruptedException, ExecutionException, TimeoutException;

在異步計(jì)算任務(wù)未執(zhí)行完成時筋讨,等待 timeout 個 unit 時間后拋出TimeoutException 異常后返回,避免了調(diào)用線程死等悉罕,可以及時釋放的問題赤屋。

boolean isDone();

如果任務(wù)完成返回true壁袄,否則返回false ,注意這里的完成包括:任務(wù)正常完成、拋出異常而完成嗜逻、任務(wù)被取消

boolean cancel(boolean mayInterruptIfRunning);

嘗試取消任務(wù)的執(zhí)行涩僻,如果任務(wù)已經(jīng)完成或者已經(jīng)被取消栈顷,則取消失敗萄凤;如果任務(wù)還沒執(zhí)行則調(diào)用了該方法室抽,則任務(wù)永遠(yuǎn)不會被執(zhí)行靡努;如果任務(wù)已經(jīng)開始運(yùn)行晓折,這時候取消任務(wù),則參數(shù)mayInterruptIfRunning決定是否要要將正在執(zhí)行的任務(wù)中斷漓概;

boolean isCancelled();

如果任務(wù)在執(zhí)行完畢前被取消了,則返回true病梢,否則返回 false。

JDK中的FutureTask

FutureTask 代表了一個可被取消的異步計(jì)算任務(wù)飘千,該類實(shí)現(xiàn)了RunnableFuture接口堂鲜,既包含Runnable 功能护奈,也包含F(xiàn)uture 功能。提供了啟動和取消任務(wù)霉旗,查詢?nèi)蝿?wù)是否完成痴奏,獲取計(jì)算結(jié)果等厌秒。

FutureTask 任務(wù)的執(zhí)行結(jié)果只有當(dāng)任務(wù)完成以后才能獲取。并且只有通過get系列方法獲取鸵闪。當(dāng)計(jì)算未完成時,get方法會阻塞等待結(jié)果蚌讼,任務(wù)一旦被執(zhí)行完成辟灰,除非運(yùn)行的時候用了runAndReset 方法篡石,否則任務(wù)不能被重啟。FutureTask 中的任務(wù)可以是Callable 類型的凰萨,也可以是Runnable 類型的继控,F(xiàn)utureTask 類型的任務(wù)可以被提交到線程池胖眷。

2.png

FutureTask 實(shí)現(xiàn)了Future 接口的所有方法,并且實(shí)現(xiàn)了Runnable 珊搀,所以其是可執(zhí)行任務(wù),可以投遞到線程池或者由線程來執(zhí)行食棕。

FutureTask 中變量state 是一個使用volatile 關(guān)鍵字修飾的(用來解決內(nèi)存可見性防止指令重排)int變量朗和。用來記錄任務(wù)的狀態(tài)簿晓。

FutureTask的局限性

FutureTask 雖然提供了用來檢查任務(wù)是否完成,等待任務(wù)執(zhí)行結(jié)果憔儿,獲取任務(wù)執(zhí)行結(jié)果的方法忆植,但是這些特色并不足以讓我們寫出簡潔的并發(fā)代碼谒臼,比如它并不清楚的表達(dá)出多個FutureTask 之間的關(guān)系,另外為了從Future獲取結(jié)果蜈缤,我們必須調(diào)用get()方法拾氓,而該方法還是會在任務(wù)執(zhí)行完畢前阻塞調(diào)用線程底哥,這明顯不是我們想要的。

我們真正想要的是:

1趾徽、可以將兩個或多個異步計(jì)算結(jié)合在一起變成一個续滋,這包括兩個或多個異步計(jì)算是獨(dú)立的時候孵奶,或者第二個異步計(jì)算依賴于第一個異步計(jì)算。

2了袁、對反應(yīng)式編程的支持朗恳,也就是當(dāng)任務(wù)計(jì)算完成后進(jìn)行通知早像,并且可以將計(jì)算結(jié)果作為下一步計(jì)算動作的參數(shù),而不是僅僅提供調(diào)用線程以阻塞的方式獲取結(jié)果卢鹦。

3臀脏、可以通過編程的方式手動設(shè)置Future 的結(jié)果冀自,F(xiàn)utureTask 則不可用讓用戶通過函數(shù)設(shè)置其計(jì)算結(jié)果,而是其任務(wù)內(nèi)部進(jìn)行設(shè)置熬粗。

4搀玖、可以等多個Future 對應(yīng)的計(jì)算結(jié)果都出來后做一些事情驻呐。

為了克服FutureTask的局限性芳来,以及滿足我們對異步編程的需要,JDK8中提供了CompletableFuture猜拾,CompletableFuture是一個可以通過編程方式顯式的設(shè)置計(jì)算結(jié)果和狀態(tài)以便讓任務(wù)結(jié)束的Future,本書后面章節(jié)我們會具體講解。

總結(jié)

推薦書目:《Java異步編程實(shí)戰(zhàn)》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挎袜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子盯仪,更是在濱河造成了極大的恐慌紊搪,老刑警劉巖全景,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蚪燕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)馆纳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門诗良,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鲁驶,“玉大人,你說我怎么就攤上這事钥弯【独螅” “怎么了脆霎?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長睛蛛。 經(jīng)常有香客問我,道長忆肾,這世上最難降的妖魔是什么荸频? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任客冈,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘和悦。我一直安慰自己退疫,他們只是感情好鸽素,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著付鹿,像睡著了一般蚜迅。 火紅的嫁衣襯著肌膚如雪舵匾。 梳的紋絲不亂的頭發(fā)上谁不,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音刹帕,去河邊找鬼。 笑死偷溺,一個胖子當(dāng)著我的面吹牛蹋辅,可吹牛的內(nèi)容都是我干的挫掏。 我是一名探鬼主播侦另,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼尉共,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了袄友?” 一聲冷哼從身側(cè)響起殿托,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤支竹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后券敌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡待诅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年叹坦,在試婚紗的時候發(fā)現(xiàn)自己被綠了卑雁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绪囱。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡莹捡,死狀恐怖篮赢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情启泣,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布遣蚀,位于F島的核電站,受9級特大地震影響纱耻,放射性物質(zhì)發(fā)生泄漏弄喘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一芒涡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卖漫,春花似錦、人聲如沸羊始。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柏卤。三九已至匀油,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間敌蚜,已是汗流浹背桥滨。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留齐媒,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓喻括,卻偏偏與公主長得像邀杏,于是被迫代替她去往敵國和親唬血。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

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