Java中Callable与FutureTask可实现带返回值的异步多线程:Callable封装有返回值任务,FutureTask包装它并实现Runnable与Future,通过get()获取结果,支持异常处理与超时控制,结合线程池更实用。

Java 中通过 Callable 和 FutureTask 可以实现带返回值的多线程异步执行,弥补了 Runnable 无法返回结果的限制。核心思路是:用 Callable 封装有返回值的任务,用 FutureTask 包装它并作为 Runnable 提交到线程中执行,再通过 get() 方法获取结果。
定义 Callable 任务
Callable 是一个泛型接口,只有一个 call() 方法,允许抛出异常并返回指定类型的值(不同于 Runnable.run() 的 void 返回)。
示例:计算两个数的和,并延时模拟耗时操作:
Callable<Integer> task = () -> {
Thread.sleep(1000);
return 10 + 20;
};
用 FutureTask 包装并启动任务
FutureTask 实现了 Runnable 和 Future,既可被线程直接执行,又支持结果查询、取消、超时等控制。
关键步骤:
- 创建
FutureTask实例,传入Callable - 将
FutureTask交给Thread或线程池执行 - 调用
get()获取结果(会阻塞直到任务完成)
FutureTask<Integer> futureTask = new FutureTask<>(task); new Thread(futureTask).start(); // 或 executor.submit(futureTask) // 获取结果(阻塞等待) Integer result = futureTask.get(); // 返回 30
处理异常与超时
get() 方法可能抛出三种异常:InterruptedException(线程被中断)、CancellationException(任务被取消)、ExecutionException(任务内部抛出的异常)。建议显式捕获。
使用带超时的 get(long timeout, TimeUnit unit) 避免无限等待:
try {
Integer result = futureTask.get(2, TimeUnit.SECONDS);
System.out.println("结果:" + result);
} catch (TimeoutException e) {
System.out.println("执行超时");
} catch (ExecutionException e) {
System.err.println("任务执行出错:" + e.getCause());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
结合线程池更实用
单独用 FutureTask + Thread 较原始;推荐配合 ExecutorService 使用,更易管理、复用资源。
注意:submit(Callable) 方法会自动包装为 Future,无需手动创建 FutureTask:
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<String> future = executor.submit(() -> {
Thread.sleep(500);
return "Hello from thread";
});
String result = future.get(); // 阻塞获取
executor.shutdown();
如仍需 FutureTask(例如想复用任务或手动控制执行),也可用 executor.execute(futureTask) 启动。

















