标题
Future可以获取线程的运行结果,get方法进行阻塞获取,那么到底是如何获取的呢?又如何阻塞的呢?又是如何唤醒的呢?取消任务是怎么取消的呢?
简单示例
先看下如何应用future和callable,简单的例子如下:
public static void main(String[] args) {
FutureTask<Integer> future = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
System.out.println("线程计算中");
Thread.sleep(3000);
System.out.println("线程计算完成");
return 111 ;
}
}) ;
Thread thread = new Thread(future) ;
thread.start();
try {
System.out.println("等待线程执行结果:");
Integer result = future.get() ;
System.out.println("获取到线程到运行结果:" + result);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
上述代码表示,用futureTask创建一个Callable任务。futureTask是Future和Runnable的实现类,负责获取线程运行结果使用get方法,callable和runnable类似,用于创建任务。
源码解读
我们带着问题去读源码,主要有以下问题
- future是如何获取callable的执行结果
- future的get方法在线程没有执行完毕时如何做到阻塞和唤醒的
- feture是如何取消任务的
基础字段
当前小节可以简单了解下,比较基础,不想看直接跳过
我们操作的实现类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
}
- 第一个构造函数,将callable任务传入进行,并设置state状态为NEW,也就是新建状态。state分为几个状态,下述会说
- 第二个构造函数,将runnable任务传入,result是自定义的返回结果,因为runnable是没有返回值的,所以支持自定义返回。
State状态值:
* Possible state transitions:
* NEW -> COMPLETING -> NORMAL
* NEW -> COMPLETING -> EXCEPTIONAL
* NEW -> CANCELLED
* NEW -> INTERRUPTING -> INTERRUPTED
private volatile int state;
private static final int NEW = 0;
private static