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 对象,用于获取结果 |
常见场景 | 简单任务,不关心结果 | 需要返回计算结果,或可能抛出异常 | 异步任务结果获取、取消任务 |