Future类的作用:
Future它是基于异步思想的,举个例子,就是我有一个耗时的任务,提交给我Future来处理,任务执行期间,我自己可以去做任何事情,并且在这个期间我还可以取消任务以及获取任务的执行状态。一段时间后,我就可以从Future那里直接取出任务的执行结果,提高了程序执行效率。FutureTask就是Future的常见实现类。
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(() -> {
try {
Thread.sleep(5000); // 模拟一个耗时任务
return 42;
} catch (InterruptedException e) {
System.out.println("任务被取消");
return -1;
}
});
// 等待一段时间后取消任务
try {
Thread.sleep(2000);
System.out.println("取消任务");
future.cancel(true); // 取消任务并中断正在执行的任务
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取任务结果
try {
System.out.println("任务结果:" + future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executor.shutdown();
}
}
PS:在这个示例中,我们使用 ExecutorService 提交一个耗时任务,并在任务执行了一段时间后取消它。在取消后,我们尝试获取任务的结果,但由于任务已经被取消,所以会抛出 CancellationException 异常。
CompletableFuture 类有什么用?
为了弥补Future缺陷,在JDK8之后引入,它提供了一种简单强大的方式处理异步的任务,和处理异步任务的结果,在它出现之前,我们只能使用Callable/Future这样的一个机制,来去获取异步线程的执行结果,但Future是通过阻塞等待方式实现,对性能不友好,而CompletableFuture可以让我们将一个耗时的任务提交给线程池进行异步的处理,然后可以继续执行其他任务,等到异步任务结束之后,会触发一个回调方法,我们可以在回调方法里面处理异步任务的执行结果。相当于优化了Future的阻塞等待问题,类似一种响应式的编程方式,它还额外提供了函数式编程,可以将多个任务串联执行的特性。
public class CompletableFutureExample {
public static void main(String[] args) {
// 创建一个CompletableFuture对象,执行异步任务
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
// 模拟一个耗时操作
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 返回结果
return "Hello, CompletableFuture!";
});
// 注册一个回调函数,处理异步任务的结果
future.thenAccept(result -> {
System.out.println("异步任务执行完成,结果为:" + result);
});
System.out.println("888");
// 阻塞等待异步任务的结果 在有需求的时候也可以选择这个阻塞的获取结果之后统一处理
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
System.out.println("666");
}
}
运行结果: