最近在分析Executor框架源碼體系,先從FutureTask類開始介紹,在Executor框架體系中,FutureTask用來表示可獲取結果的異步任務。FutureTask實現了Future接口和Runnable,FutureTask提供了查詢異步任務是否計算結束以及獲取最終的異步任務的結果以及取消異步任務的一些經常使用的方法,源碼對應的jdk版本是1.8。
java
public interface Future<V> {
//提供取消任務的抽象方法
boolean cancel(boolean mayInterruptIfRunning);
//提供判斷任務是否取消的抽象方法
boolean isCancelled();
//提供判斷任務是否完成的抽象方法
boolean isDone();
//提供獲取異步任務的執行結果的抽象方法,會拋出中斷異常和執行時異常
V get() throws InterruptedException, ExecutionException;
//提供超時的獲取異步任務的執行結果的抽象方法,會拋出中斷異常、超時異常、執行時異常
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
} 複製代碼
//函數式接口,不清楚的看下個人另外一篇函數式接口介紹https://juejin.im/post/5c7d1254e51d45720f72264c
@FunctionalInterface
public interface Runnable {
//只有一個run方法
public abstract void run();
}複製代碼
//實現於Runnable、Future接口
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}複製代碼
//state是FutureTask的狀態,任務的狀態,state狀態流轉存在4種狀況
//任務順利執行:NEW -> COMPLETING -> NORMAL
//任務執行異常:NEW -> COMPLETING -> EXCEPTIONAL
//任務取消:NEW -> CANCELLED
//任務中斷:NEW -> INTERRUPTING -> INTERRUPTED
private volatile int state;
//任務初始化狀態
private static final int NEW = 0;
//任務已經完成,但結果尚未被賦值給outcome,COMPLETING在下面的介紹set方法和setException方法中會看到,屬於中間態
private static final int COMPLETING = 1;
//任務正確執行完成的狀態,屬於終態
private static final int NORMAL = 2;
//任務執行出現異常的狀態,屬於終態
private static final int EXCEPTIONAL = 3;
//任務在NEW狀態調用cancel方法的取消狀態,下面cancel方法會介紹到,屬於終態
private static final int CANCELLED = 4;
//任務被中斷中的狀態,即線程Thread還沒調用interrupt方法前的狀態,屬於中間態
private static final int INTERRUPTING = 5;
//即線程Thread調用interrupt方法後的狀態,屬於終態
private static final int INTERRUPTED = 6;
//任務的執行體
private Callable<V> callable;
//最終輸出結果,任務正確執行完的最終結果,或者任務執行出現異常的異常對象
private Object outcome;
//執行當前任務的線程
private volatile Thread runner;
//等待隊列,當前任務在其餘線程中還沒執行完,其餘線程調用當前FutureTask對象的get方法,會將其線程阻塞起來,包裝成隊列,好比有個FutureTask在線程t中執行,還未執行完(COMPLETING狀態以前纔會阻塞,在下面的await),主線程調用此任務的get方法
private volatile WaitNode waiters;
private static final sun.misc.Unsafe UNSAFE;
private static final long stateOffset;
private static final long runnerOffset;
private static final long waitersOffset;
static {
try {
UNSAFE = sun.misc.Unsafe.getUnsafe();
Class<?> k = FutureTask.class;
stateOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("state"));
runnerOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("runner"));
waitersOffset = UNSAFE.objectFieldOffset
(k.getDeclaredField("waiters"));
} catch (Exception e) {
throw new Error(e);
}
}複製代碼
先下班了,回去再繼續寫框架