1. Runnable
- 最早期的接口,用来封装任务逻辑。
- 没有返回值、不能抛出受检异常。
java
Runnable task = () -> System.out.println("Hello Runnable");
new Thread(task).start();
2. Callable
- JDK 1.5 引入,和
Runnable类似,但 有返回值,可以抛出异常。
java
Callable<Integer> task = () -> {
return 42;
};
ExecutorService pool = Executors.newSingleThreadExecutor();
Future<Integer> future = pool.submit(task);
System.out.println(future.get()); // 输出 42
3. Future
- 代表一个 异步任务的结果 ,用来获取
Callable执行的返回值。 - 提供了
get()、cancel()、isDone()等方法。
java
Future<Integer> future = pool.submit(() -> 42);
if (!future.isDone()) {
System.out.println("任务还没完成");
}
System.out.println(future.get()); // 阻塞等待返回 42
三者关系
Runnable:只管执行,无返回值。Callable:可执行 + 有返回值。Future:拿结果的票据,执行完后从这里取。
markdown
Runnable Callable
│ │
▼ ▼
提交给 ExecutorService(线程池)
│
▼
Future
一般配合线程池使用:
java
ExecutorService pool = Executors.newFixedThreadPool(3);
Future<String> f = pool.submit(() -> "Hello Callable");
System.out.println(f.get()); // 从 Future 拿结果
🔑 口诀
- Runnable:干活,不给结果。
- Callable:干活,能返回结果,还能抛异常。
- Future:小票,凭票取结果。
| 特性 | Runnable | Callable<V> | Future<V> |
|---|---|---|---|
| 所在包 | java.lang |
java.util.concurrent |
java.util.concurrent |
| 主要作用 | 封装一个可执行任务 | 封装一个可执行任务(可返回结果/抛异常) | 表示异步任务的结果/控制 |
| 核心方法 | void run() |
V call() throws Exception |
get(), cancel(), isDone(), isCancelled() |
| 返回值 | 无返回值 | 有返回值(泛型 V) | 保存并提供 Callable/Runnable 的执行结果 |
| 异常处理 | 不能抛出受检异常 | 可以抛出受检异常 | get() 时会封装为 ExecutionException 抛出 |
| 使用方式 | new Thread(runnable).start() 或提交到线程池 |
提交到线程池执行 | 提交任务时返回 Future 对象,用于获取结果 |
| 常见场景 | 简单任务,不关心结果 | 需要返回计算结果,或可能抛出异常 | 异步任务结果获取、取消任务 |