Future
是 Java 并发编程中的一个重要接口,它代表了异步计算的结果。当你提交一个任务给线程池或其他执行者时,你会得到一个 Future
对象,它可以用来查询计算是否完成、等待计算结果或取消任务。
Future
原理:
异步计算:
Future
允许你异步地执行任务,这意味着你可以立即继续执行其他代码,而不必等待任务完成。
结果获取:
- 可以通过
Future
接口的get()
方法来获取任务的结果。如果任务尚未完成,get()
方法会阻塞调用线程直到任务完成。
- 可以通过
取消任务:
- 如果任务尚未开始或正在执行,可以通过
Future
接口的cancel()
方法来取消任务。
- 如果任务尚未开始或正在执行,可以通过
检查任务状态:
- 可以通过
isDone()
方法来检查任务是否已经完成。
- 可以通过
Future
的工作流程:
提交任务:
- 将一个实现了
Callable
或Runnable
接口的任务提交给ExecutorService
。
- 将一个实现了
获取
Future
:- 执行任务时,
ExecutorService
会返回一个Future
对象。
- 执行任务时,
等待结果:
- 调用
Future
的get()
方法来等待任务完成并获取结果。如果任务已完成,get()
方法会立即返回结果;如果任务尚未完成,get()
方法会阻塞直到任务完成。
- 调用
处理结果:
- 一旦
get()
方法返回结果,就可以对结果进行处理。
- 一旦
Future
的使用场景:
异步处理:
- 当需要执行长时间运行的任务,并且不想阻塞主线程时。
并行计算:
- 当需要并行执行多个任务,并且需要在所有任务完成后进行一些操作时。
任务取消:
- 当需要提供任务取消功能时,可以通过
Future
来实现。
- 当需要提供任务取消功能时,可以通过
Future
的实现:
Java Future
接口有几个实现类,如 FutureTask
,它是 Future
和 Runnable
的组合,通常用于提交具体任务。
示例代码:
import java.util.concurrent.*;
public class FutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
// 提交一个Callable任务
Future<String> future = executor.submit(() -> {
// 模拟长时间运行的任务
Thread.sleep(1000);
return "Result of the task";
});
// 在其他地方继续执行其他任务
System.out.println("Doing other work while waiting for the result...");
// 获取任务结果
String result = future.get(); // 这里会阻塞,直到任务完成
System.out.println(result);
// 关闭执行者服务
executor.shutdown();
}
}
注意事项:
get()
方法可能会抛出InterruptedException
,如果等待结果时当前线程被中断。get()
方法还可能抛出ExecutionException
,如果任务执行时抛出了异常。Future
只能用于一次性的结果获取,一旦结果被获取或任务被取消,Future
就不能再被使用。
使用
get()
方法的异常处理:- 当调用
Future.get()
方法时,如果异步任务执行过程中抛出了异常,它会封装在ExecutionException
中抛出。可以通过捕获ExecutionException
来处理异常。Future<?> future = executor.submit(callableTask); try { future.get(); // 等待任务完成并获取结果 } catch (InterruptedException e) { // 处理线程被中断的情况 Thread.currentThread().interrupt(); // 重置中断状态 } catch (ExecutionException e) { // 处理异步任务执行过程中的异常 Throwable cause = e.getCause(); // 获取实际的异常原因 // 处理异常原因 }
- 当调用
使用
CompletableFuture
:CompletableFuture
是Future
的增强版,它提供了更丰富的 API 来处理异步任务,包括异常处理。CompletableFuture<Void> future = CompletableFuture.supplyAsync(supplierTask) .thenApply(function) .thenAccept(consumer) .exceptionally(throwable -> { // 处理异常 return null; // 返回值可以根据需要定制 });
链式调用
exceptionally
方法:- 在
CompletableFuture
的链式调用中,exceptionally
方法可以用来捕获和处理整个链式调用中的异常。CompletableFuture<?> future = CompletableFuture.supplyAsync(supplierTask) .exceptionally(ex -> { // 处理异常 return null; // 返回值可以根据需要定制 });
- 在
使用
try-catch
块:- 在调用
Future.get()
时,使用try-catch
块来捕获和处理可能抛出的InterruptedException
和ExecutionException
。
- 在调用