Callable接口用于创建有返回值且可抛受检异常的线程任务,需配合FutureTask或ExecutorService使用,通过get()获取结果;其泛型设计、异常支持及与Runnable的本质区别是核心要点。

Java中Callable接口用于创建有返回值的线程任务,它弥补了Runnable无法返回结果和抛出受检异常的限制。核心在于配合FutureTask或线程池(如ExecutorService)使用,通过get()方法获取异步执行结果。
Callable与Runnable的关键区别
Callable是一个泛型接口,声明为interface Callable,其中V是返回值类型;而Runnable无返回值、不抛受检异常。
-
Callable.call()方法返回一个泛型结果,并可抛出Exception -
Runnable.run()返回void,且不能直接抛出受检异常 -
Callable不能直接传给Thread构造器,必须包装为FutureTask或提交给ExecutorService
使用FutureTask包装Callable执行任务
FutureTask实现了Runnable和Future,既能被Thread执行,又能获取结果、判断状态、取消任务。
示例:
立即学习“Java免费学习笔记(深入)”;
Callabletask = () -> { Thread.sleep(1000); return 42; }; FutureTask futureTask = new FutureTask<>(task); new Thread(futureTask).start(); System.out.println(futureTask.get()); // 阻塞等待,输出42
通过ExecutorService提交Callable获取Future
这是更常用、更推荐的方式,便于统一管理线程生命周期和结果集合。
- 调用
executor.submit(callable)返回Future -
future.get()阻塞获取结果;future.get(timeout, unit)支持超时控制 - 可批量提交多个
Callable,用executor.invokeAll()统一获取List>
注意:get()会阻塞当前线程,若任务未完成或抛异常(如ExecutionException),需捕获处理。
异常处理与任务取消要点
Callable.call()中抛出的异常会被封装进ExecutionException,由Future.get()抛出;原始异常可通过getCause()获取。
- 调用
future.cancel(true)可尝试中断正在运行的任务(依赖任务内部响应中断) -
future.isDone()、future.isCancelled()可用于状态检查 - 避免在循环中频繁调用
get()而不设超时,以防线程长时间挂起










