【Android 异步操作】FutureTask 分析 ( Future 接口解析 | Runnable 接口解析 | Callable 接口解析 )
文章目錄
- 一、Future 接口
- 1、Future 接口簡介
- 2、取消任務方法
- 3、Future 接口源碼注釋
- 二、Callable 接口
- 三、Runnable 接口
上一篇博客 【Android 異步操作】AsyncTask 異步任務 ( FutureTask 模擬 AsyncTask 執行過程 | AsyncTask 執行過程回顧 | FutureTask 分析 ) 中 , 使用 FutureTask 模擬 AsyncTask 執行 , 簡單介紹了 FutureTask<V> 類 , 和 RunnableFuture<V> 接口 ;
本篇博客將分析 Future 接口 , 和 Runnable 接口 , 以及 FutureTask 的運行機制 ;
相關參考文檔 :
- FutureTask
- RunnableFuture
- Future
- Runnable
- Callable
FutureTask 實現了 RunnableFuture 接口 , RunnableFuture 接口實現了 Future 接口和 Runnable 接口 , FutureTask 創建時傳入 Callable 對象 , 該對象的 call() 方法就是在子線程執行的異步方法 ;
一、Future 接口
1、Future 接口簡介
Future 作用 : Future 是 異步計算結果 ;
提供了以下方法 :
- 檢查計算是否完成
- 檢查計算是否取消
- 等待計算完成 , 獲取計算結果
- 取消任務
獲取結果有如下兩個條件 :
- 調用 get() 方法獲取計算結果
- 計算必須執行完成 , 否則會阻塞直到計算完成 , 才能解除阻塞
調用 get() 方法獲取計算結果 , 如果計算沒有完成 , 該方法會阻塞 , 直到計算完成之后 , 阻塞才會解除 , 同時返回執行結果 ;
取消任務執行 : 調用 cancel() 方法 , 可以取消異步任務的執行 ; 如果計算完畢 , 該任務無法被取消 ;
使用 Future 的可取消性 : 如果想要 使用 Future 的可取消的特性 , 不提供可用結果 , 可以將類型聲明為 Future<?> , 并返回 null 作為基礎任務的結果 ;
2、取消任務方法
boolean cancel(boolean mayInterruptIfRunning) 方法 : 嘗試取消任務的執行 ;
① 取消失敗 : 如果任務已經完成 , 或 已經被取消 , 或 因為其它原因 不能被取消 , 該嘗試可能會失敗 ;
② 取消成功 : 如果取消成功 , 并且該任務在取消時還沒有開始執行 , 該任務之后也不會被執行 ;
③ boolean mayInterruptIfRunning 參數 : 如果任務已經開始執行 , mayInterruptIfRunning 參數確定 , 在嘗試終止任務時 , 該執行任務的線程 , 是否應該被中斷 ;
④ 方法返回值 : 該方法返回時有以下行為 ;
- 在這之后如果調用 isDone() 方法 , 會返回 true , 說明該任務已經執行完成 ;
- 在這之后如果調用 isCancelled() 方法 , 會返回 true , 表明該任務已經被取消 ;
3、Future 接口源碼注釋
package java.util.concurrent;/*** Future 是異步計算結果 ; * 提供了以下方法 : 檢查計算是否完成 , 檢查計算是否取消 , 獲取計算結果 , 取消任務 ; * * 獲取結果有如下兩個條件 : 調用 get() 方法獲取計算結果 , * 計算必須執行完成 , 否則會阻塞直到計算完成 , 才能解除阻塞 ; * * 取消任務執行 : 調用 cancel() 方法 , 可以取消異步任務的執行 ; 如果計算完畢 , 該任務無法被取消 ; * 使用 Future 的可取消性 : 如果想要使用 Future 的可取消的特性 , 不提供可用結果 , * 可以將類型聲明為 Future<?> , 并返回 null 作為基礎任務的結果 ;*/ public interface Future<V> {/*** 嘗試取消任務的執行 ; * 如果任務已經完成 , 或已經被取消 , 或因為其它原因不能被取消 , 該嘗試可能會失敗 ;* 如果取消成功 , 并且該任務在取消時還沒有開始執行 , 該任務之后也不會被執行 ;* 如果任務已經開始執行 , mayInterruptIfRunning 參數確定 , 在嘗試終止任務時 , * 該執行任務的線程 , 是否應該被中斷 ; * 該方法返回時 * - 在這之后如果調用 isDone() 方法 , 會返回 true , 說明該任務已經執行完成 ; * - 在這之后如果調用 isCancelled() 方法 , 會返回 true , 表明該任務已經被取消 ; ** @param mayInterruptIfRunning * true 執行該任務的線程應該被中斷 ; * false 執行中的線程應該被執行完成 ; * * @return 任務無法取消時會返回 false , 一般是任務已經執行完成 ; * 成功取消任務 , 返回 true ; */boolean cancel(boolean mayInterruptIfRunning);/*** 如果任務在正常完成前被取消 , 就返回 true ;*/boolean isCancelled();/*** 如果任務執行完畢 , 返回 true ;* 影響任務執行的因素 : * - 正常終止* - 出現異常* - 用戶取消 * 上述所有情況出現 , 都表示任務執行完畢 ; */boolean isDone();/*** 等待任務完成 , 返回執行結果 ; */V get() throws InterruptedException, ExecutionException;/*** 等待任務完成 , 返回執行結果 ; ** @param 最長等待時間* @param 等待時間單位* @return 任務執行結果 */V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException; }
二、Callable 接口
Callable<V> 簡介 : Callable 是一個任務 , 返回 V 類型結果 , 或者 拋出異常 ; 實現類需要實現 call() 方法 , 該方法沒有參數 ;
Callable<V> 與 Runnable 對比 :
-
該 Callable 接口與 Runnable 接口類似 , 兩個接口都設計為實現類的對象實例 , 可能都要 在另外的線程執行 ;
-
Runnable 接口的 run() 方法 不返回返回值 , 不能拋出檢查出的異常 ;
-
Callable<V> 接口的 call() 方法可以 返回返回值 , 可以拋出異常 ;
package java.util.concurrent;/*** Callable<V> 是一個任務 , 返回 V 類型結果 , 或者拋出異常 ; * 實現類需要實現 call() 方法 , 該方法沒有參數 ; * * 該 Callable<V> 接口與 Runnable 接口類似 , * 兩個接口都設計為實現類的對象實例 , 可能都要在另外的線程執行 ; * * Runnable 接口的 run() 方法不返回返回值 , 不能拋出檢查出的異常 ; */ @FunctionalInterface public interface Callable<V> {/*** 計算出一個結果 , 如果無法完成 , 拋出異常 ; */V call() throws Exception; }
三、Runnable 接口
Runnable 接口作用 : Runnable 接口的實現類實例 , 需要在一個線程中被執行 ; 該實現類必須實現 run() 方法 , 該方法返回值和參數都是 void ;
Runnable 接口設計 :
-
設計原則 : 該接口被設計為 , 為那些處于活動狀態的對象 , 并且這些對象想要執行代碼 , 提供一個通用協議 ;
-
如 : Thread 類實現了 Runnable 方法 ;
-
活動狀態 : 處于活動狀態的含義是 , 線程已經被開始了 , 還不能被停止 , 如果想要執行代碼 , 必須在其它線程中執行 ;
創建線程優先策略 :
-
創建線程 : Runnable 為類提供了不需要繼承 Thread 類 , 之外的活動的途徑 ; 一個類實現了 Runnable 接口 , 在不繼承 Thread 的前提下運行 , 方法是將其傳入 Thread 構造函數 ;
-
推薦方案 :在大部分情況下 , 如果你只打算去覆蓋 run 方法 , 并且沒有其它的方法 , 應該使用 Runnable 接口 , 不建議使用 Thread 類 ;
不要輕易去繼承一個類 , 除非開發者想要去修改或者增強父類的某些行為 ;
/*** Runnable 接口的實現類實例 , 需要在一個線程中被執行 ; * 該實現類必須實現 run() 方法 , 該方法返回值和參數都是 void ; * * 該接口被設計為 , 為那些處于活動狀態的對象 , 并且這些對象想要執行代碼 , 提供一個通用協議 ; * 如 : Thread 類實現了 Runnable 方法 ; * 處于活動狀態的含義是 , 線程已經被開始了 , 還不能被停止 , 如果想要執行代碼 , 必須在其它線程中執行 ; * * 另外 , Runnable 為類提供了不需要繼承 Thread 類 , 之外的活動的途徑 ; * 一個類實現了 Runnable 接口 , 在不繼承 Thread 的前提下運行 , 方法是將其傳入 Thread 構造函數 ; * 在大部分情況下 , 如果你只打算去覆蓋 run 方法 , 并且沒有其它的方法 , * 應該使用 Runnable 接口 , 不建議使用 Thread 類 ; * * 類不應該繼承一個類 , 除非開發者想要去修改或者增強父類的某些行為 , 這是很重要的 ; */ @FunctionalInterface public interface Runnable {/*** 當一個對象實現了 Runnable 接口 , 用于創建一個線程時 , * 啟動線程會在該線程中 , 調用該對象的 run() 方法 ; * * run() 方法的通用規則是 , 在該方法中可以執行任何操作 ; */public abstract void run(); }
總結
以上是生活随笔為你收集整理的【Android 异步操作】FutureTask 分析 ( Future 接口解析 | Runnable 接口解析 | Callable 接口解析 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 异步操作】AsyncT
- 下一篇: 【运筹学】线性规划数学模型 ( 知识点回