1. FutureTask
FutureTask是一个可取消的异步计算任务。
FutureTask实现了RunnableFuture接口,而RunnableFuture接口继承自Future接口和Runnable接口。
Runnable接口是一个任务,是可以被Thread执行的任务。其中只有一个run方法
2. Runnable接口
package java.lang;
@FunctionalInterface
public interface Runnable {
/**
* 当一个对象是实现了这个接口的时候,那么就会被用在创建线程的时候,当线程启动的时候这个run方法将会被执行
*/
public abstract void run();
}
2. Future接口
FutureTask接口代表了异步计算的结果,同时也提供了操作这个任务的功能。
package java.util.concurrent;
/**
* 这个future代表了异步计算的结果
* 方法提供了校验这个计算是否完成,以及等待计算完成然后取回计算结果
* 在计算结束时,可以使用get方法继续取回,如果需要的话可以阻塞到他完成
* 取消由 {@code cancel} 方法执行。
* 提供了其他方法来确定任务是正常完成还是被取消。一旦计算完成,就不能取消计算。
* 如果为了可取消性而想使用 {@code Future} 但不提供可用结果,
* 您可以声明形式 {@code Future<?>} 的类型并返回 {@code null} 作为结果基础任务。
*/
public interface Future<V> {
/**
* 尝试去取消执行这个任务,如果任务已经完成,已经取消,或者由于某些原因不能被取消,那么这个尝试将会失败。
* 如果执行成功,且调用cancel方法时这个任务还没启动,那么这个任务将不再启动
* 如果 任务已经启动,mayInterruptIfRunning这个参数决定了执行这个任务的线程在尝试停止这个任务时是否应该被中断
* 当这个方法返回时,随后的isDone方法调用都会返回true,如果这个方法返回true,则随后的isCanceled方法调用也会返回true
* 如果值为true,执行此任务的线程应该被中断;否则,允许完成正在进行的任务
* 如果返回false的话,说明这个任务没有被取消掉,通常是因为这个任务已经执行完了
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* 返回true,如果这个任务在他执行完毕之前被cancel掉了
*/
boolean isCancelled();
/**
* 如果任务已经完成,则返回true
* 完成可能是由于正常终止、异常或取消——在所有这些情况下,此方法将返回 {@code true}。
*/
boolean isDone();
/**
* 如有必要,等待计算完成,然后取回其结果。等待过程中可以被中断
*/
V get() throws InterruptedException, ExecutionException;
/**
* 如有必要,最多等待给定的计算完成时间,然后获取其结果(如果可用)。等待过程中可以被中断,如果等待超时则抛出TimeoutException
*/
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
3. RunnableFuture接口
这个接口继承自Runnable接口和Future接口。是一个链接了Runnable的Future
package java.util.concurrent;
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* 将此 Future 设置为其计算结果,除非它已被取消。
* 这里为什么要重复定义一下run方法?
* 个人感觉是为了标识清楚,run方法也是需要实现的
* 从业务逻辑上说,两者的逻辑不一样,这个run方法的规定的逻辑是需要将Future设置到结果中。而Runnable接口的run方法逻辑是任务执行的方法
*/
void run();
}
可以看到,Runnable接口中已经有了一个run方法的定义,在RunnableFuture接口中也有一个run方法的定义。为什么要重复定义run方法。
个人感觉是为了标识清楚,run方法也是需要实现的
从业务逻辑上说,两者的逻辑不一样,在RunnableFuture中这个run方法的定义是在run方法执行完毕后需要将Future设置到结果中,且在方法执行过程中可以被future中的cancel方法取消;而Runnable接口的run方法逻辑只是任务执行的方法,可以被Thread执行。
4. FutureTask
4.1 FutureTask中的属性,钩子函数以及钩子函数
public class FutureTask<V> implements RunnableFuture<V> {
private volatile int state;
private static final int NEW = 0;
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;
/**
* 这个Callable在运行后清除
*/
private Callable<V> callable;
/**
* 从 get() 返回的结果或抛出的异常
* 非volatile的,受状态读写保护
*/
private Object outcome;
/**
* 运行Callable的线程,在调用run()方法时被CAS替换
*/
private volatile Thread runner;
/**
* 等待线程的Treiber栈
*/
private volatile WaitNode waiters;
/**
* 构造方法,将参数callable设置好,并设置状态为NEW
*/
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
/**
* 将给定的Runnable对象和给定的返回值生成一个callable对象,并设置为callable属性,然后设置状态为NEW
*/
public FutureTask(Runnable runnable, V result) {
//返回了一个能执行Runnable且能返回在指定值的Callable对象
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
/**
* 返回是否被取消了
* CANCELLED
* INTERRUPTING
* INTERRUPTED
*/
public boolean isCancelled() {
return state >= CANCELLED;
}
/**
* 返回是否已经执行结束
*/
public boolean isDone() {
return state != NEW;
}
/**
* 钩子函数,在finishCompletion()方法中调用
*/
protected