FutureTask的使用
CompressFutureTask是一個(gè)自己定義的繼承FutureTask的類,其中mCallbackDispatcher也是一個(gè)接口用于分發(fā)可以在這里忽略,我們關(guān)心的是set方法
在起初的時(shí)候我并不知道這個(gè)set方法如何使用,查看文檔也是一知半解,所以決定分析源碼,下來就看下源碼。
public class CompressFutureTask<T> extends FutureTask<T> {
private CallbackDispatcher<T> mCallbackDispatcher;//自己定義的分發(fā)對象
private CompressFutureTask(Callable<T> callable) {
super(callable);
}
private CompressFutureTask(Runnable runnable, T result) {
super(runnable, result);
}
public CompressFutureTask(Callable<T> callable, CallbackDispatcher<T> dispatcher) {
super(callable);
this.mCallbackDispatcher = dispatcher;
}
@Override
protected void set(T t) {
super.set(t);
MainThreadExecutor.postToMainThread(t, mCallbackDispatcher);
}
@Override
protected void setException(Throwable t) {
super.setException(t);
}
}
其中最核心的是set方法,這個(gè)set方法是在什么時(shí)候調(diào)用呢?
我們先從觀察FutureTask來看。
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;
}
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
//同時(shí)實(shí)現(xiàn)了Future接口和Runnable接口
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}
public class FutureTask<V> implements RunnableFuture<V> {
我們繼續(xù)看看FutureTask的構(gòu)造
private volatile int state;
private static final int NEW = 0;//代表一種狀態(tài)
private static final int COMPLETING = 1;
private static final int NORMAL = 2;
private static final int EXCEPTIONAL = 3;
private static final int CANCELLED = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED = 6;
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
我們繼續(xù)看第二種構(gòu)造的內(nèi)部
Executors.callable(runnable, result);
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
private static final class RunnableAdapter<T> implements Callable<T> {
private final Runnable task;
private final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
所以FutureTask構(gòu)造究其根源就是有一個(gè)callable和state,其中callable是我們目前研究的核心。
callable的核心就是call方法。FutureTask第二個(gè)構(gòu)造所產(chǎn)生的callable也就是將Runnable 包裝了一層,放執(zhí)行call方法的時(shí)候就執(zhí)行對應(yīng)Runnable方法。
我們現(xiàn)在看看FutureTask.run()
public void run() {
if (state != NEW || !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;//注意這里是構(gòu)造的時(shí)候擁有的
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();//然后調(diào)用call方法
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);//然后設(shè)置結(jié)果,至于result在這些里面沒有操作,只是在call方法執(zhí)行完之后才執(zhí)行,所以result這個(gè)是要自己的call中操作的對象。
}
} finally {
runner = null;
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
所以只要在線程池中添加任務(wù)之后當(dāng)執(zhí)行任務(wù)的時(shí)候調(diào)用run的時(shí)候,就會觸發(fā)這一操作,先是調(diào)用call方法,然后將返回結(jié)果給result,最后set到FutureTask方法中,這些操作都是在子線程中執(zhí)行的。當(dāng)我們需要刷入主線程中的時(shí)候就要用我們的分發(fā)自定義的東西,然后把這個(gè)結(jié)果通過主線程的Handle進(jìn)行刷入主線程。