future.get() 必须配合超时使用,避免线程无限阻塞;isdone()/iscancelled() 仅查状态,不能替代 get();原始 future 不支持回调,轮询是反模式;submit(runnable) 返回的 future 无法获取结果,需用 callable。
Future.get() 会阻塞当前线程,必须配合超时使用
调用 Future.get() 是最直接的取结果方式,但它默认无限期等待,一旦任务卡住或执行时间不可控,调用线程就会一直挂起。生产环境几乎从不裸用无参 get()。
- 务必使用带超时的重载:
future.get(3, TimeUnit.SECONDS),避免线程被长期占用 - 超时后抛出
TimeoutException,需显式捕获并处理(如降级、重试、记录告警) - 如果任务已取消或执行异常,
get()会包装抛出CancellationException或ExecutionException,不能只 catchException
isDone() 和 isCancelled() 只能查状态,不能代替 get()
这两个方法返回布尔值,常被误当作“安全取值”的替代方案。其实它们只反映任务生命周期状态,和结果内容完全无关。
-
isDone()为 true 仅表示任务已结束(无论成功、失败或取消),但结果可能还没真正计算完(比如刚进入完成状态但尚未设置 outcome 字段) -
isCancelled()为 true 时,get()必然抛CancellationException,此时不应再尝试获取业务数据 - 轮询
isDone()+ 睡眠再重试,属于低效且易出错的 busy-wait,应优先考虑CompletableFuture的回调机制
Future 本身不支持回调,强行轮询或 sleep 是反模式
原始 Future 接口没有 thenApply、whenComplete 这类能力,这是它和 CompletableFuture 的本质区别。很多老项目因不了解这点,写出如下代码: