package ajiayou.index0711.demo03; import java.util.Random; import java.util.concurrent.Callable; public class Match2 implements Callable<Integer> { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public Integer call() throws Exception { Random r = new Random(); //这里是随机数 int speed = r.nextInt(100); int dist = 0; for(int i = 1; i<=100; i++) { //睡眠100毫秒 Thread.sleep(30); //Thread.currentThread().getName() //获得当前线程的名称 dist += i * speed; System.out.println(this.getName() + "已前进" + (dist) + "米(" + speed + "米/秒)"); } return dist; } } /* 注释补充:创建一个线程 Java 提供了三种创建线程的方法: 1.通过继承 Thread 类本身; 2.通过实现 Runnable 接口; 3.通过 Callable 和 Future 创建线程。 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。 */ package ajiayou.index0711.demo03; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class Test2 { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService es = Executors.newFixedThreadPool(3); //创建了3个线程 Match2 m = new Match2(); m.setName("java"); Match2 m1 = new Match2(); m1.setName("mysql"); Match2 m2 = new Match2(); m2.setName("boot"); //开始对上面的线程进行执行 Future<Integer> future = es.submit(m); Future<Integer> future1 = es.submit(m1); Future<Integer> future2 = es.submit(m2); Integer i = future.get(); Integer i1 = future1.get(); Integer i2 = future2.get(); System.out.println(m.getName() + "共跑了" + i + "米"); System.out.println(m1.getName() + "共跑了" + i1 + "米"); System.out.println(m2.getName() + "共跑了" + i2 + "米"); } }
时间: 2025-07-21 11:58:30 浏览: 18
<think>我们正在回答用户的问题:如何使用Callable和Future来创建并管理线程,并获取线程执行后的返回值。
根据引用[1][2][3]可知,Callable和Future是在Java 1.5版本开始引入的,用于解决Runnable无法返回结果的问题。
实现步骤:
1. 创建Callable接口的实现类,并实现call()方法,在call()方法中编写线程执行逻辑并返回结果。
2. 使用FutureTask类来包装Callable对象,FutureTask实现了RunnableFuture接口,而RunnableFuture又继承了Runnable和Future接口。
3. 将FutureTask对象作为Thread的target创建线程并启动。
4. 调用FutureTask对象的get()方法获取线程执行后的返回值(该方法会阻塞直到任务完成)。
下面我们通过一个完整的示例代码来展示如何使用Callable和FutureTask获取线程返回值。</think>### Java 多线程中使用 Callable 和 Future 获取返回值的实现方法
在 Java 多线程编程中,`Callable` 和 `Future` 提供了比 `Runnable` 更强大的线程管理能力,主要解决了 **线程返回值获取** 和 **异常处理** 的问题。以下是完整实现方法:
#### 1. 核心组件说明
| 组件 | 作用 | 特点 |
|------|------|------|
| `Callable<V>` | 替代 Runnable 的任务接口 | 可返回结果($V$类型),可抛出异常[^3] |
| `Future<V>` | 异步计算结果容器 | 提供结果获取、任务取消、状态检查等方法[^1] |
| `FutureTask` | Future 的基础实现类 | 可包装 Callable 对象,同时实现 Runnable 接口[^2] |
#### 2. 实现步骤
```java
import java.util.concurrent.*;
public class CallableDemo {
public static void main(String[] args) throws Exception {
// 步骤1:创建Callable任务
Callable<Integer> task = () -> {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
Thread.sleep(10); // 模拟耗时操作
}
return sum; // 返回计算结果[^1]
};
// 步骤2:包装为FutureTask
FutureTask<Integer> futureTask = new FutureTask<>(task);
// 步骤3:启动线程执行任务
new Thread(futureTask).start();
// 步骤4:获取异步计算结果(阻塞等待)
int result = futureTask.get();
System.out.println("计算结果: " + result); // 输出: 5050
}
}
```
#### 3. 关键操作详解
1. **创建 Callable 任务**
```java
Callable<String> task = () -> {
// 业务逻辑...
return "执行结果";
};
```
2. **获取结果(阻塞方式)**
```java
String result = future.get(); // 阻塞直到任务完成[^2]
```
3. **超时控制(避免永久阻塞)**
```java
try {
result = future.get(5, TimeUnit.SECONDS); // 最多等待5秒
} catch (TimeoutException e) {
future.cancel(true); // 取消任务[^4]
}
```
4. **状态检查**
```java
if (!future.isDone()) {
System.out.println("任务仍在运行");
}
```
#### 4. 线程池集成(推荐方式)
```java
ExecutorService executor = Executors.newFixedThreadPool(3);
// 提交多个任务
Future<Integer> future1 = executor.submit(() -> 100);
Future<Integer> future2 = executor.submit(() -> 200);
// 批量获取结果
int total = future1.get() + future2.get(); // 300
executor.shutdown(); // 关闭线程池
```
#### 5. 异常处理机制
```java
Callable<Integer> task = () -> {
if (errorCondition) {
throw new RuntimeException("自定义异常");
}
return 42;
};
try {
future.get();
} catch (ExecutionException e) {
Throwable cause = e.getCause(); // 获取真实异常[^3]
System.out.println("任务异常: " + cause.getMessage());
}
```
#### 6. 适用场景对比
| 场景 | Runnable | Callable+Future |
|------|----------|-----------------|
| 需要返回值 | ❌ 不支持 | ✅ 支持 |
| 异常传播 | ❌ 受限 | ✅ 完整异常栈 |
| 超时控制 | ❌ 困难 | ✅ 内置支持 |
| 任务取消 | ❌ 有限 | ✅ 精细控制 |
> 通过 `Callable` 和 `Future` 的组合,Java 多线程实现了 **任务执行** 与 **结果获取** 的解耦,使异步计算更加灵活可靠[^1][^3]。实际开发中建议配合线程池使用,避免频繁创建线程的开销[^4]。
阅读全文
相关推荐


















