外观
一句话答案
Callable 有返回值可抛异常(vs Runnable),Future 获取异步结果(get 阻塞),FutureTask 是桥梁,局限性推荐 CompletableFuture。
核心要点
Runnable vs Callable:
| 维度 | Runnable | Callable |
|---|---|---|
| 返回值 | void | V |
| 异常 | 不能抛出 checked | 可以抛出 Exception |
| 方法 | run() | call() |
Future 接口:
get():阻塞等待结果get(timeout, unit):超时等待isDone():是否完成cancel():取消任务
FutureTask 使用:
java
Callable<Integer> task = () -> heavyComputation();
FutureTask<Integer> ft = new FutureTask<>(task);
new Thread(ft).start();
Integer result = ft.get(); // 阻塞局限性: get() 阻塞、无法组合多个 Future → 推荐 CompletableFuture
追问与易错
追问方向:
- Future.get() 阻塞有什么问题?
- FutureTask 可以被多个线程提交吗?
- Callable 和 Runnable 的适用场景?
易错点:
- ❌ Future.get() 不设超时——可能永久阻塞
- ❌ 忘记处理 ExecutionException
💡 记忆锚点
Runnable 是寄信不回执,Callable 是寄信带回执单(Future)。get() 就是站在邮局柜台死等回执——等太久会卡死,所以后来升级成了 CompletableFuture,信到了自动打电话通知你。