持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,[点击查看活动详情]
future是jdk1.5新增的接口,这个接口是干什么的,大家都知道传统的runnable接口没有返回值,但是future可以获取返回值,且可以捕获异常,我们来看下future的定义。
Future表示异步计算的结果。 提供方法以检查计算是否完成,等待其完成,以及检索计算结果。 只有在计算完成时才能使用方法get检索结果,必要时将其阻塞直到准备就绪。 取消由cancel方法执行。 提供了其他方法来确定任务是否正常完成或被取消。 计算完成后,无法取消计算。 如果使用Future以获取可取消性但未提供可用结果,则可以声明Future表单的Future并返回null作为基础任务的结果。
下面来看下future常用的api:
boolean cancel(boolean mayInterruptIfRunning)
cancel:翻译过来就是取消,意思就是尝试取消当前任务,如果任务已完成,已取消或由于某些其他原因无法取消,则此尝试将失败。 如果成功,并且在cancel时此任务尚未启动,则此任务永远不会运行,参mayInterruptIfRunning
的意思是如果任务已经启动,则mayInterruptIfRunning参数确定执行此任务的线程是否应在尝试停止任务时中断。此方法返回后,对isDone()的后续调用将始终返回true 。 随后电话isCancelled()总是返回true如果此方法返回true。
isCancelled
isCancelled:是否取消的,如果是任务正常完成之前被取消那么返回true。
isDone
isDone:任务是否完成,不管是正常完成、被取消、还是异常完成都是返回true。
get
get:该方法是获取返回结果的,有一个重载,如果不传参数那么就是一直等待知道获取到结果,,另外可传时间参数,超过传入时间则抛出超时异常。
下面来进入实际编码,假设有以下场景,有5个任务(使用for循环代替)需要使用线程池并行执行且需要获取这些任务的返回值输出(实际业务可以是其他操作)
ExecutorService executorService = Executors.newFixedThreadPool(5);
List<Future> futures = new ArrayList<>();
for (int i = 0; i < 5; i++) {
Future<Integer> future = executorService.submit(() -> {
TimeUnit.SECONDS.sleep(10);
int nextInt = ThreadLocalRandom.current().nextInt(10);
return nextInt;
});
futures.add(future);
}
for (Future future : futures) {
if (future.isDone() && future.isCancelled()) {
System.out.println("future : " + future.get());
}
}
需要注意的是我在每个任务执行的时候都让其sleep了10s,且在输出时加了isDone和isCancelled的判断,也就是说当前任务必须是完成的才会输出,显然任务执行没这么快,我们看下输出结果,如下图
但是如果把判断去掉再次执行,如下图:
发现有输出,但是需要等待10s,也就是说future的get操作是阻塞的。