futureTask可以用来异步获取执行结果,也就是说,业务代码的线程和主线程,可以同时执行,在需要获取执行结果的时候,调用其get()方法,就会阻塞主线程,直到获取到执行结果之后,再继续执行主线程的代码,具体的用法,不再详细叙述
使用
public class FutureTaskTest {
public static void main(String[] args) throws Exception{
FutureTask<Integer> futureTask = new FutureTask(() -> {
System.out.println("测试futureTask");
TimeUnit.SECONDS.sleep(3);
return 2;
});
new Thread(futureTask).start();
System.out.println("主线程可以继续执行其他代码...,.");
System.out.println("模拟现在需要用到线程执行结果:");
Integer result = futureTask.get();
System.out.println("获取到执行结果:"+result);
}
}
测试futureTask
主线程可以继续执行其他代码...,.
模拟现在需要用到线程执行结果:
获取到执行结果:2
这个demo就是模拟futureTask的执行过程,在get()方法被调用之后,如果没有获取到执行结果,最后一句代码是无法执行的,会一直阻塞,直到拿到线程的执行结果,才会继续执行主线程
源码
在futureTask源码中,有一个变量,state
/**
* The run state of this task, initially NEW. The run state
* transitions to a terminal state only in methods set,
* setException, and cancel. During completion, state may take on
* transient values of COMPLETING (while outcome is being set) or
* INTERRUPTING (only while interrupting the runner to satisfy a
* cancel(true)). Transitions from these intermediate to final
* states use cheaper ordered/lazy writes because values are unique
* and cannot be further modified.
* 这是官方的注释,并且标明了状态流转的过程
* Possible state transitions:
* NEW -> COMPLETING -> NORMAL
* NEW -> COMPLETING -> EXCEPTIONAL
* NEW -> CANCELLED
* NEW -> INTERRUPTING -> INTERRUPTED
*/
private volatile int state;
/**
* 在构造函数中,设置为new
*/
private static final int NEW = 0;
/**
* 线程正常执行完毕,先通过CAS将state修改为completing
* 是normal的前一个状态
*/
private static final int COMPLETING

FutureTask允许异步获取执行结果,通过get()方法实现主线程阻塞,等待任务完成。源码中,state变量在get()调用时起到关键作用,若任务未完成则通过awaitDone()调用LockSupport.park()阻塞。run()方法启动线程,setException()和set(result)更新state并唤醒等待的线程,整个流程与AQS类似。
最低0.47元/天 解锁文章
766

被折叠的 条评论
为什么被折叠?



