Runnable 无返回值且不能抛受检异常,Callable 可返回结果并抛出受检异常,前者适用于无需结果的后台任务,后者适用于需获取计算结果或处理受检异常的场景。

Runnable 和 Callable 都是用来定义任务的接口,核心区别在于:Runnable 不能返回结果、不能抛出受检异常;Callable 可以返回结果、可以抛出受检异常。
返回值支持不同
Runnable 的 run() 方法返回 void,适合执行无结果的后台操作,比如日志清理、心跳发送。
Callable 的 call() 方法返回泛型类型 V,能通过 Future 获取执行结果,适合需要计算结果的任务,比如异步查数据库、远程接口调用。
- Runnable 示例:new Runnable() { public void run() { System.out.println("执行中"); } }
- Callable 示例:new Callable
() { public String call() { return "完成"; } }
异常处理能力不同
Runnable 的 run() 方法只能抛出运行时异常(RuntimeException 及其子类),抛受检异常(如 IOException)会编译报错。
立即学习“Java免费学习笔记(深入)”;
Callable 的 call() 方法声明抛出 Exception,可直接 throw IOException、SQLException 等受检异常,由调用方通过 Future.get() 捕获处理。
- Runnable 中写 throw new IOException(); → 编译失败
- Callable 中写 throw new IOException(); → 合法,Future.get() 会包装成 ExecutionException
使用场景和配合对象不同
Runnable 可直接提交给 Thread、ExecutorService,兼容性更广。
Callable 必须通过 ExecutorService.submit() 提交,返回 Future 对象来获取结果或控制任务(取消、查询状态)。
- Thread 构造器只接受 Runnable,不接受 Callable
- ExecutorService.execute() 接收 Runnable;submit() 既可接 Runnable(返回 void Future),也可接 Callable(返回带结果的 Future)
本质都是函数式接口
两者都只有一个抽象方法,支持 Lambda 表达式简化写法:
- Runnable lambda:() -> System.out.println("Hello")
- Callable lambda:() -> { Thread.sleep(100); return "Done"; }
基本上就这些。选哪个,关键看任务要不要返回值、会不会抛受检异常。










