Java的FutureTask實(shí)現(xiàn)原理
-
Executor.submit(Callable call)
submit步驟:- 將callable包裝成一個FutureTask轩褐,這個類既是一個Future唧瘾,又是一個Runnable,實(shí)現(xiàn)了RunnableFuture接口(適配器模式)
- 線程池提交任務(wù)
提交任務(wù):將任務(wù)包裝成一個worker,這個worker既持有任務(wù)羡疗,又持有線程(線程池中實(shí)際持有的是worker)慕爬。worker添加到線程池后畅铭,啟動線程淡溯。執(zhí)行邏輯如下:- 執(zhí)行worker持有的任務(wù)
- 任務(wù)執(zhí)行完了以后設(shè)置FutureTask的outCome
- 喚醒在FutureTask上面等待的線程WaitNode結(jié)構(gòu)(java.util.concurrent.FutureTask#finishCompletion)
- 從線程池中的阻塞隊(duì)列中獲取新的任務(wù)(在這里控制線程的存活時間),如果獲取到新的元素拒逮,執(zhí)行步驟1
- 從線程池中移除worker罐氨,任務(wù)結(jié)束
- 返回futureTask
-
Future.get()
- 如果任務(wù)已經(jīng)計(jì)算出來結(jié)果,直接返回結(jié)果
- 否則構(gòu)建將當(dāng)前線程包裝成一個WaitNode(鏈表),CAS把生成的waitNode插入到FutureTask的header滩援,然后掛起當(dāng)前線程栅隐。(java.util.concurrent.FutureTask#awaitDone)
線程池的執(zhí)行流程
- 如果線程池中thread的size小于coreSize,新建線程執(zhí)行任務(wù)
- 如果線程池中的thread數(shù)量大于coresize,將任務(wù)添加到任務(wù)隊(duì)列中(盡可能高效的復(fù)用線程)
- 如果任務(wù)不能添加到任務(wù)隊(duì)列并且thread的size小于maxSize租悄,新建線程執(zhí)行任務(wù)
- 執(zhí)行拒絕策略