Callable :
public interface Callable<V> {
V call() throws Exception;
}
Future :
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit);
}
FutureTask :
public class FutureTask<V> implements RunnableFuture<V> ;
RunnableFuture :
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}
Runnable :
public interface Runnable {
public abstract void run();
}
FutureTask内部持有Callable, Thread, 将上面几个接口与类联系在一起, 所以从FutureTask源码进行分析, 如何将这些接口进行了关联;
FutureTask内部用到了适配器模式
AsyncTask内部用到了FutureTask, 以AsyncTask为例进行分析, 争取同时搞明白AsyncTask和FutureTask;
AsyncTask有两种调用方式 :
1、创建AsyncTask对象, 自己实现doInBackground()方法, 然后调用execute()方法;
2、直接调用AsyncTask内部的静态execute()方法;
因为第一种方式用到了FutureTask, 所以先针对这种方式进行分析:
AsyncTask_AsyncTask() :
public abstract class AsyncTask {
public AsyncTask() {
mWorker = new WorkerRunnable<...>() {
public Result call() throws Exception {...}
};
mFuture = new FutureTask<...>(mWorker) {
@Override
protected void done() {...}
};
}
}
初始化AsyncTask时创建了WorkerRunnable和FutureTask对象, FutureTask持有WorkerRunnable对象的引用;
AsyncTask_WorkerRunnable :
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
public interface Callable<V> {
V call() throws Exception;
}
WorkerRunnable实现于Callable接口;
初始化AsyncTask之后便是调用execute方法让doInBackground执行于子线程中并获取返回值, 显示于主线程方法onProgressUpdate()中;
AsyncTask_execute() :
public class AsyncTask {
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
mStatus = Status.RUNNING;
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
}
1、mStatus默认为Status.PENDING, 当第一次调用execute时, mStatus随着程序的执行, 只有两个值RUNNING, FINISHED, 所以第二次调用execute时, 会抛出异常, 也即说明AsyncTask的一个缺点, 这种方式的适用场景, 单线程, 一个AsyncTask对象只能执行一个Task;
2、虽然第二种方式可以支持执行多个Task, 但是由于execute是静态方法, 并不支持cancel等控制Task生命周期的方法;
3、exec.execute()由线程池内部逻辑可知会触发mFuture的run方法执行;
AsyncTask_sDefaultExecutor :
public class AsyncTask {
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
}
execute只接受Runnable对象, mActive实际指向FutureTask, 当Executor.execute(Runnable)时会触发Runnable内部run方法的执行, 而FutureTask此时接收的是Callable对象;
FutureTask_Callable :
public class FutureTask {
public FutureTask(Callable<V> callable) {
this.callable = callable;
}
public void run() {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
setException(ex);
}
if (ran)
set(result);
}
}
}
1、FutureTask内部的run()方法又是调用了Callable对象的call方法;
2、Future提供了一系列的控制线程周期的方法;通过AsyncTask的cancel控制FutureTask的生命周期;
所以四者的关系是:
1、由于Executor的execute()方法只接收Runnable, 并且会触发Runnable内部的run方法的执行, 所以FutureTask必须实现Runnable;
2、但是Runnable的run方法没有返回值, 而有些特殊情况又需要拿到最终线程执行的结果, 而Callable刚好可以拿到结果, 所以在其内部持有Callable的引用;
3、需要控制线程什么什么周期的问题, 而Future刚好提供了这些功能, 所以FutureTask又实现Future接口;
但是如果FutureTask需要支持Runnable怎么办?目前run方法内部实际调用的是Callable的call()方法:
所以适配器模式在这里发挥了作用, 也反映了适配器的一个特点, 是为了解决问题而生;
public class FutureTask {
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
}
}
public class Executors{
public static <T> Callable<T> callable(Runnable task, T result) {
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构造函数支持传入Runnable对象, 可以看到此时传入的Runnable实际通过适配器模式被转化为了Callable对象, 而Callable实际指向RunnableAdapter, RunnableAdapter内部持有Runnable, 内部的call方法又会出发Runnable的run方法的执行;
网友评论