Callable配合Future是Java获取多线程执行结果的标准方式:1. Callable替代Runnable实现带返回值、可抛受检异常的任务;2. 通过线程池submit提交返回Future;3. 调用get()阻塞获取结果,支持超时与异常处理。

Java 中 Callable 接口配合 Future 是获取多线程执行结果的标准方式,核心在于:用 Callable 替代 Runnable 实现带返回值的任务,再通过线程池提交后拿到 Future 对象,调用其 get() 方法阻塞获取结果。
为什么不用 Runnable?
Runnable.run() 没有返回值、也不能抛出受检异常,无法满足“执行完要拿结果”的需求。Callable.call() 支持泛型返回值(如 Callable<String>),且可抛出异常,语义更完整。
基本配合步骤
只需三步,就能让子线程干活并取回结果:
- 定义一个类实现
Callable<T>,重写call()方法,返回你要的结果(比如计算结果、查询数据等) - 使用
ExecutorService(推荐Executors.newFixedThreadPool(…))调用submit(callable),返回Future<T> - 调用
future.get()获取结果——该方法会阻塞,直到任务完成;也可用get(timeout, unit)设置超时避免无限等待
实际代码示例
下面是一个计算 1 到 1000000 和的简单例子:
ExecutorService pool = Executors.newSingleThreadExecutor();
Callable<Long> task = () -> {
long sum = 0;
for (int i = 1; i <= 1_000_000; i++) sum += i;
return sum; // 返回 Long 类型结果
};
Future<Long> future = pool.submit(task);
try {
Long result = future.get(); // 阻塞等待,获取结果
System.out.println("计算结果:" + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
pool.shutdown();
}
注意几个关键细节
Future.get() 是阻塞操作,如果任务还没结束,主线程会一直等;
get() 抛出的 ExecutionException 包裹了 call() 中的真实异常,记得用 e.getCause() 提取原始异常;
Future.isDone() 可轮询判断是否完成,适合不想阻塞又想及时响应的场景;
Future.cancel(true) 可尝试中断正在运行的任务(前提是任务本身响应中断)。


















