概述
Future是一个接口,它的主要目的,是为了我们能够方便的控制在线程中的任务的进度。在实际使用中,它常与Callable一起使用。本文主要为了理清,Java中,线程任务的各种类的关系。
Runable与Callable
Runable与Callable都是纯接口,它是Java中,对于任务的抽象概念。其中,我们看一看它们的源码就可以知道了。
public interface Runnable {
abstract void run();
}
public interface Callable<V> {
V call() throws Exception;
}
Runable与Callable的差别就是一个有返回,一个没返回。
Future
Future是线程运行任务的控制器,我们可以通过它,控制任务的启停,获取任务的状态,获取任务返回的结果。
先看源码:
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;
}
我们可以看到Future提供的API。其中,值得注意的是,get
方法会阻塞当前线程。
在Java中,提供了一种基本的实现:FutureTask
FutureTask
实现了RunnableFuture<V>
接口,而 RunnableFuture<V>
则是继承了,Runnble
和Future<V>
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
FutureTask
提供了两个构造方法:
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
}
其中输入Runnable
在FutureTask
的内部也会转化为Callable
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;
}
}
所以,我们使用时,是将需要执行的逻辑放在Callable中,然后
当我们将FutureTask
传入线程池,或者新线程时,因为它本身具有Runable的接口,所以可以像正常Runnable
那样执行。又因为其持有了一个Callable。所以,当任务执行完时,会有输出结果,FutureTask
会保存这个结果,等待外部来取。
如果此时任务尚未执行完成,外部就企图获取结果,会阻塞当前线程。
这个地方看起逻辑复杂,其实只要看一眼源码就很清楚了。
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (unit == null)
throw new NullPointerException();
int s = state;
if (s <= COMPLETING &&
(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
throw new TimeoutException();
return report(s);
}
其中awaitDone
就是一个封装了超时和中断的await
。
当任务执行完成后,阻塞结果,返回结果。
网友评论