Future和Callable
Runnable的缺陷
- 不能返回一个返回值
- 不能抛出checked Exception
- 因为run使用void修饰的也不能抛出异常
Callable接口
- 类似于Runnable,被其他线程执行的任务
- 实现call方法(类似于实现run方法)
- 是有返回值的也可以抛出异常
Future类
- 作用:一个方法可能会很耗时,就可以用一个子线程来执行这个耗时的方法,就不用一直等,直到想要获取结果时就可以通过Future来控制
- Future和Callable的关系:
- 可以通过Future的get方法获取Callable的执行结果
- 可以通过Future的isDown判断任务是否执行完毕
- 还有取消等方法
- 在call()未执行完毕之前,调用get()的线程就会被阻塞,直到call()方法返回了结果,线程才能获取结果并且切换到runnable状态
- Future是一个存储器,它存储了call()任务的结果,但是这个任务的执行时间是无法提前确定的,所以这取决于call()方法执行的情况
Future的主要方法
get():get方法的行为取决于Callable任务的状态
- 任务正常完成:get方法会立刻返回结果
- 任务没有完成:get将阻塞并直到任务完成
- 任务执行过程中抛出异常:get方法会抛出ExecutionException,如果已经发生异常,但是没有get也不会抛出
- 任务被取消:get方法会抛出CancellationException
- 任务超时:会抛出TimeoutException
get(long timeout,TimeUnit unit):设置一个超时时间的获取,如果超时了会抛出TimeoutException
cancel:取消任务的执行,可以传入true/false,代表是否中断正在执行的任务
- 如果任务还没有开始执行,任务正常取消,返回true
- 如果任务已取消或者已完成,那么会执行失败,返回false
- 如果任务在执行,就不会直接取消该任务,会根据填写的参数判断
- 当知道任务能正确处理Interrupt的时候才传入true
- 如果未能处理interrupt、不清楚任务是否支持取消、需要等待已经开始的任务执行完成就需要传入false
isDone:判断线程是否执行完毕(执行完毕不一定是执行成功)
isCancelled:判断是否被取消
代码示例get
1 | public static void main(String[] args) { |
演示批量获取结果
1 | public static void main(String[] args) { |
演示延时get以及cancel
1 | public static final Info DEFAULT = new Info("无消息"); |
FutureTask
- FutureTask来获取Future任务结果
- FutureTask是一种包装器,可以把Callable转化成Future和Runnable,他同时实现二者的接口
- 它既可以作为Runnable被线程执行,又可以作为Future获取Callable的返回值
代码演示
1 | public class FutureTaskDemo { |
注意点
- 当循环获取future结果时,容易发生部分线程执行很慢的情况,get方法调用时应使用延时获取
- Future的生命周期不能后退,比如线程结束后就不能变成new或者runnable状态







