筆者今天學習FutureTask包裝器,簡單點講該包裝器就是對底層線程任務執行的包裝,包括返回值,異常拋出等。好比說咱們如今有個任務須要交個run方法進行執行,這時候咱們調用Thread的start方法,而後JVM開啓一個線程幫咱們執行該方法,可是run返回值爲void,而且不能拋出異常,這是就須要包裝器對其進行包裝。今天筆者就來本身實現下FutureTask簡單的底層實現原理。函數
- 首先建立MyCallable接口,添加未實現的myCall的方法該方法返回T類型的返回值,後面交給自定義MyFutureTask任務包裝器執行。
- 編寫MyFutureTask類實現Runnable接口,爲何實現這個接口呢,由於咱們須要將myCall接口交給JVM底層的線程去執行。一般Thread的構造函數會傳入Runnable接口進去。而後調用Runnable的run方法。等會咱們也須要開啓一個線程傳入MyFutureTask對象進行。讓底層開啓一個線程幫咱們執行MyFutureTask的fun方法。
- MyFutureTask裏面須要對MyCallable進行引用,而且經過構造方法對其進行賦值,在MyFutureTask的run方法對MyCallable的myCall方法進行執行。myCall有返回值因此咱們須要定義個全局的結果來對其進行存儲。可是咱們如何判斷當前線程是否執行完畢,因此咱們引入了一個簡單的線程狀態(固然真正的底層線程狀態會比較多)只有NEW和COMPLETE,NEW表示線程建立而且任務還未執行完,COMPLETE表示線程已經執行完任務。
- MyFutureTask的重寫Runnable的run方法,調用myCallable的myCall的方法執行任務,並獲取返回結果。這裏JVM底層會開啓一個線程幫咱們執行run方法。
- FutureTask的會提供get來獲取任務執行結果,因此咱們也簡單模擬了get的實現原理。在get方法中咱們去判斷線程任務的執行狀態,若是狀態爲COMPLETE則將結果返回出去,若是不爲COMPLETE則當前線程調用wait方法進入等待狀態。(注意這裏其實有兩個不一樣的線程。一般主線程會執行get方法,而另一個線程執行run方法。)
- 接着在run方法中若是線程任務執行完後,這修改其狀態爲COMPLETE,並喚醒等待的線程。這裏涉及到了線程的通信,我只簡單的提一下,後續會有專題進行記錄。
- 最後進行測試