FutureTask 获取结果需遵循“阻塞可控、异常必捕、状态可察”:必须用带超时的 get() 避免无限等待,捕获 InterruptedException、ExecutionException 和 TimeoutException,调用前可用 isDone() 探查状态,结果无用时及时 cancel(true) 释放资源。

获取 FutureTask 的执行结果,核心在于“阻塞可控、异常必捕、状态可察”。直接调用 get() 会阻塞,但不设超时或不处理异常,极易导致线程挂起或错误静默。
用带超时的 get() 避免无限等待
无参 get() 会一直等下去,哪怕任务卡死或线程池已关闭。生产环境必须使用带超时版本。
-
futureTask.get(3, TimeUnit.SECONDS):最多等 3 秒,超时抛TimeoutException - 超时时间需结合任务实际耗时设定,避免过短误判失败,过长拖慢响应
- 若任务本身支持中断(如含
Thread.sleep()或BlockingQueue.take()),超时取消更有效
必须捕获三类异常
FutureTask 将任务内异常“捕获并重抛”,不会在子线程中直接崩溃主线程,但必须由你显式处理。
-
InterruptedException:主线程在等待时被中断(如服务优雅停机) -
ExecutionException:任务内部抛出的原始异常,可通过e.getCause()获取真实原因 -
TimeoutException:仅出现在带超时的get()中,表示任务未按时完成
提前检查 isDone() 减少无效阻塞
如果业务允许“结果就绪再取”,可在调用 get() 前快速探查状态,避免无谓等待。
立即学习“Java免费学习笔记(深入)”;
if (futureTask.isDone()) { result = futureTask.get(); }- 注意:
isDone()返回true并不意味着结果已就绪(可能刚抛异常),get()仍需 try-catch - 轮询方式(如 while(!isDone()) Thread.sleep(10))效率低,优先用超时
get()替代
及时 cancel() 释放资源
若结果已无用(如用户取消请求、页面跳转),应主动调用 cancel(true) 终止任务。
-
cancel(true)尝试中断正在运行的线程,适用于可响应中断的任务 -
cancel(false)仅取消未启动的任务,适合不可中断的计算型任务 - 取消后调用
get()会立即抛CancellationException,需单独捕获


















