FutureTask常常用于包裝任務附井,提交給Executor執(zhí)行携丁,本博客介紹JDK1.7的實現(xiàn)至壤,如果想看JDK1.8的實現(xiàn)請移步FutureTask源碼詳解(JDK1.8)
繼承結構
實現(xiàn)
FutureTask對外方法
FutureTask對外方法都通過內(nèi)部類Sync來實現(xiàn)
Sync內(nèi)部類實現(xiàn)
總結
通過內(nèi)部繼承AQS的一個私有類Sync來實現(xiàn)操作代理的况增;Sync 實現(xiàn)了AQS的tryAcquireShared()和tryReleaseShared()方法
FutureTask代的get()方法代理到AQS的acquireSharedInterruptibly()方法上
這個方法內(nèi)部回調重寫的tryAcquireShared()方法來判斷acquire操作是否可以成功涌哲。
- 成功的條件為:state為執(zhí)行完成狀態(tài)RAN或已取消CANCELLED富蓄,且runner不為null剩燥。
- 如果成功則從get()方法返回,失敗則進入AQS等待隊列中立倍,直到其他線程release(run,cancel)灭红。
- 當其他線程執(zhí)行AQS的release方法喚醒當前線程后,當前線程再次執(zhí)行tryAcquireShared()方法將返回1(大于0的數(shù)表示成功)口注,當前線程離開等待隊列并喚醒后繼線程(級聯(lián)喚醒的效果)变擒。
- 最后返回計算的結果或者拋出異常。
FutureTask的run()和cancel()方法代理到AQS的release()方法上
release()會回調tryReleaseShared()方法疆导,看一下run方法的執(zhí)行過程:
- 執(zhí)行任務(Callable.call());
- 以原子的方式更新同步狀態(tài)赁项,如果這個操作成功就設置代表計算結果的變量result的值為Callable.call()的返回值,然后調用AQS的releaseShared()方法釋放同步狀態(tài)
- 先回調tryReleaseShared()方法澈段,設置運行任務的線程為null悠菜,然后返回true。
- 然后執(zhí)行AQS.releaseShared()方法败富,喚醒線程等待隊列中的第一個線程(第一個被喚醒后悔醋,后面依次被喚醒)
- 執(zhí)行FutureTask.done()方法,這是一個空方法兽叮》医荆可以用來在這個方法內(nèi)查詢狀態(tài)是否完成猾愿。