Future是异步结果的凭证而非执行器,仅支持查状态、取结果(须用带超时的get)、取消任务;无回调、不支持链式编排,复杂场景应升级CompletableFuture。
Future 是用来“收货”的异步凭证,不是执行器
Future 接口本身不执行任务,它只是你提交 Callable 或 Runnable 到线程池(如 ExecutorService)后,立刻拿到的一张“结果欠条”。你不能靠它启动线程,也不能靠它调度任务——它只负责三件事:查状态(isDone() / isCancelled())、取结果(get())、取消任务(cancel())。常见误解是把它当“异步工具类”用,结果发现 Future 自己不会跑、不会回调、也不会组合,纯靠轮询或阻塞,非常被动。
get() 会卡死主线程,超时才是生产环境标配
get() 没有参数版本是最大陷阱:一旦任务卡住(比如数据库连接未响应、远程调用 hang 住),调用线程将无限等待,整个服务可能因此雪崩。必须用带超时的 get(long, TimeUnit),并配合异常处理:
- 捕获
TimeoutException后建议立即future.cancel(true),避免资源泄漏 - 捕获
ExecutionException说明任务内部抛了异常,需 unwrap 原因:e.getCause() - 捕获
InterruptedException后通常应恢复中断状态:Thread.currentThread().interrupt()
示例关键片段:
try {
String result = future.get(2, TimeUnit.SECONDS);
} catch (TimeoutException e) {
future.cancel(true); // 中断正在运行的线程
return "default_value";
}
isDone() 轮询看似非阻塞,实则浪费 CPU
有人为避免 get() 阻塞,写循环反复调用 isDone() + Thread.sleep(10),这叫“忙等+休眠”,既不优雅也不高效。它在任务短时完成时响应差,在长耗时任务中又白占 CPU 周期。真正适合非阻塞场景的是 CompletableFuture 的回调机制(如 thenAccept),而原生 Future 没有内置回调能力。如果硬要用 Future 实现轻量通知,只能靠外部轮询+条件变量,不推荐。