callable 接口需配合 executorservice 使用,本身不启动线程,仅定义带返回值和异常处理能力的任务;executorservice 负责调度、资源复用与生命周期管理。

Callable 接口必须配合 ExecutorService 才能发挥价值——它本身不启动线程,只是定义了带返回值和异常能力的任务;ExecutorService 负责调度执行、资源复用与生命周期管理。
定义泛型 Callable 任务
Callable 是函数式接口,直接用 lambda 或实现类均可,关键是要指定返回类型(如 String、Integer 或自定义对象),并在 call() 方法中编写逻辑:
- call() 可返回任意泛型类型 V,编译器据此推断 Future
- call() 声明抛出 Exception,允许处理受检异常(比如 IOException、SQLException)
- 避免在 call() 中吞掉异常;应主动捕获并封装为业务结果,或让 ExecutionException 透出供上层统一处理
提交任务获取 Future 对象
调用 executor.submit(callable) 后立即返回 Future
- Future 就像一张“取货单”,代表尚未完成的异步计算结果
- Future.get() 会阻塞,直到任务结束;推荐始终使用带超时的版本:get(3, TimeUnit.SECONDS)
- 若任务被取消、超时或执行出错,get() 分别抛出 CancellationException、TimeoutException、ExecutionException
批量执行与结果收集
当需并发运行多个同类或异构任务时,优先用 invokeAll():
- 传入 List
>,返回 List >,保持提交顺序 - 支持整体超时控制:invokeAll(tasks, 5, TimeUnit.SECONDS),任一任务超时即中断全部未完成任务
- 遍历 Future 列表时仍需对每个 future 调用 get() 获取具体结果,并处理各自异常
线程池关闭与资源清理
ExecutorService 不会自动销毁,必须显式关闭,否则 JVM 无法退出:
- 先调用 shutdown():拒绝新任务,但允许已提交任务继续执行
- 再调用 awaitTermination(timeout, unit) 等待所有任务自然结束
- 若超时未结束,可选调用 shutdownNow() 尝试中断正在运行的线程(注意:不是所有任务都响应中断)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











