多线程 Future 的用法
在 Java 中,Future是 “异步任务的结果容器”,用于获取多线程异步执行的结果。当提交一个任务到线程池时,会返回一个Future对象,通过该对象可判断任务是否完成、获取任务结果、取消任务,解决了 “主线程等待子线程完成” 的低效问题。
# 1. 核心接口与类
- Future:核心接口,定义 4 个关键方法:
V get():阻塞等待任务完成,返回任务结果(若任务被取消,抛出CancellationException;若任务异常,抛出ExecutionException);V get(long timeout, TimeUnit unit):带超时的get(),超时未完成则抛出TimeoutException;boolean isDone():判断任务是否已完成(正常完成、异常、取消均返回true);boolean cancel(boolean mayInterruptIfRunning):取消任务,mayInterruptIfRunning=true表示若任务正在执行,中断线程;false表示仅取消未执行的任务。
- FutureTask:
Future的实现类,同时实现Runnable接口,可作为任务提交到线程池,也可直接用Thread启动。 - CompletableFuture:Java 8 新增,增强
Future功能,支持链式调用、异步回调、异常处理,解决了Future需阻塞获取结果的问题(推荐使用)。
# 2. 常见用法示例
# (1)基础用法:通过线程池获取 Future
java 运行
import java.util.concurrent.*;
public class FutureDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 1. 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(1);
// 2. 提交任务,返回Future
Future<Integer> future = executor.submit(() -> {
// 模拟异步任务(如计算、查数据库)
Thread.sleep(2000);
return 1 + 1; // 任务结果
});
// 3. 主线程可做其他事情(非阻塞)
System.out.println("主线程执行其他任务...");
// 4. 获取任务结果(阻塞,直到任务完成)
Integer result = future.get();
System.out.println("异步任务结果:" + result); // 输出:2
// 5. 关闭线程池
executor.shutdown();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# (2)带超时的 get ():避免无限阻塞
java 运行
try {
// 超时时间2秒,超过则抛出TimeoutException
Integer result = future.get(2, TimeUnit.SECONDS);
} catch (TimeoutException e) {
System.out.println("任务超时,取消任务");
future.cancel(true); // 取消任务
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# (3)FutureTask:直接用 Thread 启动
java 运行
public class FutureTaskDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 1. 创建FutureTask(包装任务)
FutureTask<String> futureTask = new FutureTask<>(() -> {
Thread.sleep(1000);
return "FutureTask任务完成";
});
// 2. 用Thread启动任务
new Thread(futureTask).start();
// 3. 获取结果
String result = futureTask.get();
System.out.println(result); // 输出:FutureTask任务完成
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# (4)CompletableFuture:异步回调(推荐)
java 运行
import java.util.concurrent.CompletableFuture;
public class CompletableFutureDemo {
public static void main(String[] args) throws InterruptedException {
// 1. 异步执行任务,无需线程池(默认用ForkJoinPool)
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "CompletableFuture任务完成";
});
// 2. 异步回调(任务完成后自动执行,无需阻塞)
future.thenAccept(result -> System.out.println("回调结果:" + result));
// 3. 主线程等待(防止程序提前退出)
Thread.sleep(2000);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 3. 注意事项
- get () 方法阻塞:
Future.get()会阻塞主线程,若任务执行时间长,会影响主线程效率,推荐用CompletableFuture的异步回调替代; - 任务取消:
cancel(true)会中断正在执行的任务,需确保任务能响应中断(如在Thread.sleep()、wait()时会抛出InterruptedException); - 异常处理:
get()会将任务中的异常包装为ExecutionException,需通过e.getCause()获取原始异常;CompletableFuture可通过exceptionally()处理异常(如future.exceptionally(e -> "默认值")); - 线程池关闭:提交任务到线程池后,需调用
executor.shutdown()关闭线程池,避免线程泄漏。
上次更新: 12/30/2025