1,Future
java.util.concurrent.Future接口提供了線程不會因為等待傳回結果而阻塞的能力。
設想一個生活場景,用于需要申請車牌,它在送出了申請之後,與長達數小時的等待過程,在這個過程裡,使用者可以做自己想做的其他事情,而無需一直在視窗等待車牌制作完成。
在這個過程中,用于可以放棄領取,也可以一直在視窗等待,也可以在視窗看看,能拿走則拿走,不行就在等一會去做别的事。
Future模式就是提供了這樣的能力,讓線程可以靈活的确定自己在何時取得結果。
2,FutureTask
java.util.concurrent.FutureTask是Future接口在concurrency包中的預設實作,它的主要用途之一是為了AbstractExecutorService提供任務支援,交由AbstractExecutorService執行的任務會被包裝成一個FutureTask,以提供延時擷取傳回值的能力。
FutureTask間接繼承自Future接口和Runnable接口,是以,它同時具備執行任務和擷取結果兩種能力,FutureTask把實作委托給了其内部的AQS來實作。
AQS是一個抽象隊列同步器,内部維護了一個等待隊列和等待狀态。
3,Sync的四種狀态
Sync設計了四種狀态,可見,Sync的實作也采用了狀态機模式。
READY:任務準備完畢,可以運作
RUNNING:任務正在運作
RAN:任務運作完畢
CANCELLED:任務取消
4,Sync的運作
innerRun的實作很簡單:
1) 檢查任務是否為READY狀态,如果不是,那麼認為已經被調用過了,直接傳回。
2) 設定任務為RUNNING狀态,表示目前Sync申領了該任務,如果該任務沒有被其它線程修改,那麼執行該任務。
3) 如果其它線程修改了該任務額狀态,例如RAN或者CANCELLED,那麼中斷執行。
5,Sync的取消
innerCancel方法的關鍵點有幾處:
1) 隻有READY或者RUN狀态的任務才能取消。
2) 根據參數來決定是否要中斷線程阻塞。
6,Sync擷取資料
innerGet方法用于異步擷取資料,其邏輯實作如下:
1) 如果任務已經執行完成了,那麼直接傳回結果。
2) 如果任務尚未完成,那麼等待任務完成後傳回結果。
通過對innerGet邏輯實作的分析,可以得出:
1) 線程通路innerGet時,如果任務不是RAN或者CANCELLED狀态,那麼線程會被阻塞。
2) result來自于innerRun()裡callable的傳回值
7,Sync和AQS
在運作/取消方法裡,調用了tryReleaseShared,在取值方法裡,調用了tryAcquiredShared,這兩個try方法來自于AQS,分别用于在共享模式下線程釋放鎖和持有鎖