1 簡介
- 使用繼承方式的好處是友善傳參,可在子類裡面添加成員變量,通過 set 方法設定參數者通過構造器進行傳遞
- 使用 Runnable 方式,則隻能使用主線程裡面被聲明為 final 變量
不好的地方是 Java 不支援多繼承,若繼承了 Thread 類,則子類不能再繼承其它類 ,而 Runable接口則無該限制 。
Thread 類和 Runnable 接口都不允許聲明檢查型異常,也不能定義傳回值。
沒有傳回值就有點麻煩,這兩種方式都沒辦法拿到任務的傳回結果,但FutureTask 可以!
不能聲明抛出檢查型異常則更麻煩一些。run()方法意味着必須捕獲并處理檢查型異常。即使小心地儲存了異常資訊(在捕獲異常時)以便稍後檢查,但也不能保證這個 Runnable 對象的所有使用者都讀取異常資訊。
可以修改Runnable實作的getter,讓它們都能抛出任務執行中的異常。但這種方法除了繁瑣也不是十分安全可靠,你不能強迫使用者調用這些方法,程式員很可能會調用join()方法等待線程結束然後就不管了。
但是現在不用擔心了,以上的問題終于在1.5中解決了。
Callable接口和Future接口的引入以及他們對線程池的支援優雅地解決了這兩個問題。
2 案例
FutureTask 相關元件如何使用的=

3 Callable
Callable函數式接口定義了唯一方法 - call()。可以在Callable的實作中聲明強類型的傳回值,甚至抛異常。
利用call()直接傳回結果,省去讀取值時的類型轉換。
- 定義
-
和阿裡面試官對線FutureTask源碼面試(上)1 簡介2 案例3 Callable4 Future - 傳回值是個泛型,使用時,不會直接使用 Callable,而是和 FutureTask 協同。
4 Future
- Callable 可以傳回線程的執行結果,在擷取結果時,就需用到Future接口
-
和阿裡面試官對線FutureTask源碼面試(上)1 簡介2 案例3 Callable4 Future - Future是 Java5 中引入的接口,當送出一個Callable對象給線程池時,将得到一個Future對象,并且它和傳入的Callable有相同的結果類型聲明。
它取代了Java5 前直接操作 Thread 執行個體做法。以前,不得不用Thread.join()或Thread.join(long millis)等待任務完成。
Future表示異步計算的結果,提供了一些方法來檢查計算是否完成,等待其完成以及檢索計算結果。
隻有在計算完成時才可以使用get方法檢索結果,必要時将其阻塞,直到準備就緒。
取消是通過cancel方法執行的。
提供了其他方法來确定任務是正常完成還是被取消。一旦計算完成,就不能取消計算。
如果出于可取消性的目的使用Future而不提供可用的結果,則可以聲明Future <?>形式的類型,并作為基礎任務的結果傳回null。
4.1 Future API
4.1.1 cancel - 嘗試取消執行任務
當任務處于不同狀态時,該方法有不同響應:
任務已完成 / 已取消 / 由于某些其他原因無法被取消
該嘗試會直接失敗
嘗試成功,且此時任務尚未開始
可以取消成功
任務已開始
mayInterruptIfRunning 參數确定是否可以中斷執行該任務的線程以嘗試停止該任務。
此方法傳回後,對 isDone 的後續調用将始終傳回 true。若此方法傳回 true,則随後對 isCancelled 的調用将始終傳回 true。
4.1.2 isCancelled - 是否被取消
如果此任務在正常完成之前被取消,則傳回true.
4.1.3 isDone - 是否完成
如果此任務完成,則傳回true。
完成可能是由于正常終止,異常或取消引起的,在所有這些情況下,此方法都将傳回true。
4.1.4 get - 擷取結果
等待任務完成,然後擷取其結果。
若:
- 任務被取消,抛 CancellationException
- 目前線程在等待時被中斷,抛 InterruptedException
- 任務抛出了異常,抛 ExecutionException