Future简介
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果等操作。它代表是异步执行的结果,意思是当异步执行结束之后,返回的结果将会保存在Future中。
当我们提交一个Callable
任务后,我们会同时获得一个Future
对象,然后,我们在主线程某个时刻调用Future
对象的get()
方法,就可以获得异步执行的结果。在调用get()
时,如果异步任务已经完成,我们就直接获得结果。如果异步任务还没有完成,那么get()
会阻塞,直到任务完成后才返回结果。
经常用到Future的场景有:
- 计算密集场景
- 处理大数据量
- 远程方法调用
五个方法
boolean cancel(boolean mayInterruptIfRunning);
方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。
如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;
如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;
如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
isCancelled();
方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
isDone();
方法表示任务是否已经完成,若任务完成,则返回true;
get();
方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
get(long timeout, TimeUnit unit);
用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
也就是说Future提供了三种功能:
- 判断任务是否完成;
- 能够中断任务;
- 能够获取任务执行结果。
Future使用
//代码来自廖雪峰网站
package com.itranswarp.learnjava;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* Learn Java from https://www.liaoxuefeng.com/
*
* @author liaoxuefeng
*/
public class Main {
public static void main(String[] args) throws Exception {
ExecutorService es = Executors.newFixedThreadPool(4);
Future<BigDecimal> future = es.submit(new Task("601857"));
System.out.println(future.get());
es.shutdown();
}
}
class Task implements Callable<BigDecimal> {
public Task(String code) {
}
@Override
public BigDecimal call() throws Exception {
Thread.sleep(1000);
double d = 5 + Math.random() * 20;
return new BigDecimal(d).setScale(2, RoundingMode.DOWN);
}
}
CompletableFuture
Future模式有一个问题,那就是将任务提交给线程后,调用线程并不知道这个任务什么时候执行完,如果执行调用get()方法或者isDone()方法判断,可能会进行不必要的等待,那么系统的吞吐量很难提高。
为了解决这个问题,JDK对Future模式又进行了加强,创建了一个CompletableFuture,它可以理解为Future模式的升级版本,它最大的作用是提供了一个回调机制,可以在任务完成后,自动回调一些后续的处理,这样,整个程序可以把“结果等待”完全给移除了。
CompletableFuture 实现了两个接口,一个是我们熟悉的 Future ,一个是 CompletionStage。
Runnable就是没有返回结果的行为。
Callable是有返回结果的行为。
Future 异步封装Callable和Runnable,委托给线程池执行后,需要取回执行的结果
CompletableFuture 封装了Future,使其拥有了回调的功能,在某个行为完成之后,可以继续进行下一个动作。
具体例子可参考下述参考资料博客中。
参考资料
https://www.cnblogs.com/thisiswhy/p/13463129.html
https://juejin.cn/post/6950065347227549703
https://www.liaoxuefeng.com/wiki/1252599548343744/1306581182447650
https://juejin.cn/post/6844904195162636295