多線程之串行實(shí)現(xiàn)

比如有這么個(gè)需求:有線程A、B。A線程是搬磚,B線程是蓋房,B必須在A完成后執(zhí)行。怎么辦?

一、用Thread的join方法

join中參數(shù)為啟動(dòng)banzhuanThread的線程等待banzhuanThread執(zhí)行的時(shí)間,時(shí)間到達(dá)后,代碼接著往下執(zhí)行。參數(shù)缺省時(shí)會(huì)一直等待時(shí)間無(wú)窮,直到執(zhí)行完成。

如果搬磚的人半路不干了(線程A未按理想情況完成),磚沒(méi)搬完,就不能開(kāi)始蓋房,此時(shí)join方法就不適合這種場(chǎng)景了。接下來(lái)就需要用到Future/FutureTask,它們能告訴你搬磚是正常完成還是其他特殊情況。

二、用Future或FutureTask:

先簡(jiǎn)單對(duì)比一下Future和FutureTask:

相同點(diǎn):

1)、Future和FutureTask都可以通過(guò)調(diào)用get(),獲得Callable中返回的結(jié)果,并且該方法是線程阻塞的;

不同點(diǎn):

1)、Future是個(gè)接口,用來(lái)展現(xiàn)異步執(zhí)行的結(jié)果;

2)、FutureTask是個(gè)類(lèi),實(shí)現(xiàn)了RunnableFuture接口(RunnableFuture又同時(shí)繼承了Runnable和Future接口);不難看出,F(xiàn)utureTask比Future多了個(gè)Runnable。這也就意味著在使用上存在一些的不同。

再來(lái)看兩個(gè)簡(jiǎn)單的例子:

首先我們自定義一個(gè)BanzhuanCallable實(shí)現(xiàn)Callable接口。Callable接口類(lèi)似Runnable,兩者都是用于多線程。最重要區(qū)別是:Runnanble不返回線程執(zhí)行結(jié)果并且也無(wú)法拋出受檢異常。而,Callabel卻可以。

搬磚Callable

1、用FutureTask實(shí)現(xiàn):

由于FutureTask實(shí)現(xiàn)了Runnable接口,所以可以直接傳參給Thread構(gòu)造方法,并調(diào)用start執(zhí)行。

用FutureTask實(shí)現(xiàn)

2、用Future實(shí)現(xiàn):

Future實(shí)現(xiàn)需用到線程池(這里為了方便直接用的Executors.newCachedThreadPool(),大家可以自行單例化一下)。


用Future實(shí)現(xiàn)

當(dāng)然,例子1中new?Thread也可以換成線程池,調(diào)用execute/submit方法。


補(bǔ)充一個(gè)知識(shí)點(diǎn):

線程池的submit傳參可以是Runnable,也可以是Callable。最后都會(huì)轉(zhuǎn)換成RunnableFuture(FutureTask就是實(shí)現(xiàn)的這個(gè)接口)。

java線程池源碼部分
java線程池源碼部分

上面講了這么多,提到Callable、Runnable、Future、FutureTask、線程池submit方法。這幾者之間的關(guān)系大家結(jié)合上面例子,稍微思考一下,應(yīng)該就很清晰了。


希望本文能夠幫到大家!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容