Callable+FutureTask支持返回值和异常传递,而Runnable不能;FutureTask兼具Runnable和Future特性,可提交执行并获取结果;配合线程池使用更高效,submit方法自动包装并支持超时控制与异常处理。

直接用 Callable 配合 FutureTask,就能让线程执行完后带回结果——它比 Runnable 更进一步,天然支持返回值和异常传递。
为什么选 Callable + FutureTask 而不是 Runnable?
Runnable 的 run() 方法没有返回值、也不能抛出受检异常;Callable 的 call() 方法可以返回任意类型(通过泛型指定),且能抛出异常,更适合需要“拿结果”的场景。FutureTask 是 Runnable 和 Future 的实现类,既可被线程执行,又能获取执行状态和结果。
基本创建与使用步骤
分三步走:
- 定义一个实现 Callable<T> 的任务类或 Lambda 表达式,T 即你想要的返回类型(比如 Integer、String)
- 把 Callable 包装成 FutureTask<T> 实例
- 将 FutureTask 当作 Runnable 提交给 Thread 启动,或丢进线程池;之后调用 get() 获取结果(会阻塞直到完成)
关键细节:get() 的阻塞与超时控制
FutureTask.get() 默认会一直等,线程没结束就卡住;实际开发中建议用带超时的重载方法:
- future.get(3, TimeUnit.SECONDS) —— 最多等 3 秒,超时抛出 TimeoutException
- 调用 get 前可用 isDone() 判断是否已完成,避免无谓等待
- 如果任务执行中抛了异常,get() 会把异常包装成 ExecutionException 抛出,getCause() 可拿到原始异常
配合线程池更实用
单独 new Thread + FutureTask 略显繁琐,更推荐交给 ExecutorService:
- 用 executor.submit(callable) 直接返回 Future,底层自动包装为 FutureTask
- submit 也支持 Runnable + 结果参数形式:submit(runnable, result),执行完直接返回 result
- 记得在合适时机调用 shutdown(),避免线程池泄露

















