Future代表了异步计算的结果,提供诸多方法检查异步计算是否完成,是否需要等待,以及获取结果。结果只能通过 get() 方法获取。
如果我们调用了get方法,但异步任务却并未完成,会陷入阻塞状态,直到异步计算结束。
表示未来异步计算的结果。提供了检查计算是否完成、等待其完成以及检索计算结果的方法。只有在计算完成时,才能使用方法get检索结果,必要时阻塞,直到它准备就绪。可通过取消方法取消执行任务。一旦计算完成,就不能取消计算。如果为了可取消性而想使用Future,但不提供可用的结果,可以声明Future<?>并作为基础任务的结果返回null。
方法
boolean cancel(boolean mayInterruptIfRunning)
;
- 取消方法执行。
- 如果任务已完成、已取消或由于其他原因无法取消,则此尝试将失败。如果成功,并且在调用cancel时此任务尚未启动,则此任务不应运行。如果任务已经启动,那么maybuitFrunning 参数确定执行此任务的线程是否应该被中断以试图停止任务。
boolean isCancelled()
;
- 任务是否已经被取消,如果此任务在正常完成之前被取消,则返回true。
- 如果cancel() 返回true,则对isCanceled的后续调用将始终返回true。
boolean isDone()
;
- 如果此任务已完成,则返回true。完成可能是由于正常终止、异常或取消造成的——在所有这些情况下,此方法都将返回true。
V get()
throws InterruptedException, ExecutionException;
- 等待任务完成,返回异步任务结果。会陷入阻塞状态。
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException;
实现类
FutureTask implements RunnableFuture
一种可取消的异步计算。这个类提供了Future的一个基本实现,提供了启动和取消计算、查询计算是否完成以及检索计算结果的方法。只有在计算完成时才能检索结果;如果计算尚未完成,get方法将阻塞。一旦计算完成,就不能重新启动或取消计算(除非使用runAndReset调用计算)。
FutureTask可用于包装可调用或可运行的对象。因为FutureTask实现Runnable,FutureTask可以提交给执行者执行。
public static void main(String[] args) {
// 定义一个任务
Callable<Integer> callable = () -> {
System.out.println("pre execution");
int randomNum = new Random().nextInt(500);
System.out.println("post execution");
return randomNum;
};
// 包装成异步任务
FutureTask<Integer> futureTask = new FutureTask<>(callable);
new Thread(futureTask).start();
try {
// 异步任务未完成,会陷入阻塞状态,直到异步计算结束。
System.out.println(futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
CompletableFuture implements Future, CompletionStage
避免使用future的get() 方法,发生阻塞的情况。
注:completionStage.java :一个任务可能会有多个阶段,当第一个阶段完成后,触发第二个阶段。以此类推。
演示 - 阶段性完成。 hello world
String join = CompletableFuture.supplyAsync(() -> "hello").thenApplyAsync(value -> value + " world").join();
System.out.println(join);
System.out.println("-----------------");
String result2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "hello";
}).thenCombine(CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "world";
}), (s1, s2) -> s1 + " " + s2).join();
System.out.println(result2);
演示 - 完成计算结果后,回调。保证获取结果时的异步性。避免阻塞。
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
try {
TimeUnit.MILLISECONDS.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务完成");
});
// 回调,不会阻塞
completableFuture.whenComplete((t, action) -> System.out.println("执行完成!"));
System.out.println("主线程执行完毕");
try {
// 推迟主线程结束时间,方便观察 子线程执行过程
TimeUnit.MILLISECONDS.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
注:资料主要来源【张龙】