方式 | 说明 | 适用场景 | 核心机制/工具 |
---|---|---|---|
1 多线程(Thread / Runnable | 直接创建线程或使用 Runnable /Callable 实现异步任务 |
简单异步、底层控制 | Thread , Runnable , ExecutorService |
2 Future 和 Callable | 提交任务并异步获取结果(阻塞式获取) | 需要返回值的异步任务 | ExecutorService.submit(Callable) ,返回 Future<T> |
3 CompletableFuture (Java 8+) | 强大的异步编程工具,支持链式调用、组合、回调、异常处理等 | 复杂异步流程编排 | CompletableFuture.supplyAsync() / thenApply() / thenCompose() 等 |
4 回调(Callback) | 异步完成后通过回调函数通知 | 事件驱动、异步IO等 | 自定义回调接口,常见于旧代码或某些框架 |
5 响应式编程(Reactive Programming) | 基于数据流和变化传播的异步非阻塞模型 | 高并发、流式处理、前后端交互 | Project Reactor(如 Mono/Flux)、RxJava |
6 Java 异步 HTTP 客户端(如 HttpClient) | 异步发送 HTTP 请求并处理响应 | 异步网络请求 | HttpClient.sendAsync() (Java 11+) |
1. 使用Thread
、Runnable
、ExecutorService
Runnable
定义 "要做什么"(异步任务的逻辑);Thread
提供 "谁来做"(单个线程作为执行载体);ExecutorService
解决 "如何高效地做"(通过线程池管理多个线程,优化资源利用)。
java
private static void async1() {
Runnable task = () -> {
for (int i = 0; i < 6; i++) {
System.out.println("异步任务执行中:" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
// 启动新线程,异步执行task中的run()方法
Thread thread = new Thread(task);
thread.start();
try {
// 主线程会等待thread执行完成
thread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("主线程继续执行...");
// 创建一个固定大小为2的线程池
ExecutorService executor = Executors.newFixedThreadPool(2);
// 提交第一个异步任务
executor.submit(task);
// 提交第二个异步任务(复用线程池中的线程)
executor.submit(() -> {
try {
Thread.sleep(1000);
System.out.println("第二个异步任务执行中");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
try {
// 等待所有任务完成
executor.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 关闭线程池
executor.shutdown();
System.out.println("线程池已关闭");
}
2. 使用Future
和 Callable
java
// 自定义任务类(实现Callable接口,有返回值)
static class Task implements Callable<String> {
private String name;
private long delay;
public Task(String name, long delay) {
this.name = name;
this.delay = delay;
}
@Override
public String call() throws Exception {
System.out.println(name + "开始执行...");
Thread.sleep(delay); // 模拟耗时操作
return name + "执行完成(耗时" + delay + "ms)";
}
}
private static void async2() {
// 1. 创建线程池(推荐根据实际需求调整核心线程数)
ExecutorService executor = Executors.newFixedThreadPool(3); // 固定3个线程的线程池
try {
// 2. 提交异步任务(返回Future对象)
Future<String> future1 = executor.submit(new Task("任务1", 2000));
Future<Integer> future2 = executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(1500); // 模拟耗时操作
return 100 + 200; // 任务结果
}
});
// 3. 主线程可以做其他事情
System.out.println("主线程执行其他操作...");
// 4. 获取任务结果(get()方法会阻塞,直到任务完成)
String result1 = future1.get();
System.out.println("任务1结果:" + result1);
Integer result2 = future2.get(3, TimeUnit.SECONDS); // 带超时的get()
System.out.println("任务2结果:" + result2);
// 5. 演示取消任务
Future<String> future3 = executor.submit(new Task("任务3", 3000));
Thread.sleep(1000); // 等待1秒后取消任务
boolean isCancelled = future3.cancel(true); // true表示中断正在执行的任务
System.out.println("任务3是否取消成功:" + isCancelled);
System.out.println("任务3是否已完成:" + future3.isDone());
} catch (InterruptedException e) {
System.out.println("线程被中断:" + e.getMessage());
} catch (ExecutionException e) {
System.out.println("任务执行出错:" + e.getMessage());
} catch (TimeoutException e) {
System.out.println("获取结果超时:" + e.getMessage());
} finally {
// 6. 关闭线程池(必须执行,否则程序不会退出)
executor.shutdown();
}
}
3. CompletableFuture (Java 8+)
kotlin
// 1. 简单异步任务(无返回值)
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("任务1:异步执行(无返回值)");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
// 2. 带返回值的异步任务
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2);
return "任务2:异步计算结果";
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
// 3. 链式操作(处理上一个任务的结果)
CompletableFuture<Integer> future3 = future2
.thenApply(result -> {
System.out.println("任务3:处理任务2的结果 -> " + result);
return result.length(); // 计算字符串长度
})
.thenApply(length -> length * 2); // 再做一次处理
// 4. 组合两个异步任务(等待两者完成后处理结果)
CompletableFuture<String> future4 = future2.thenCombine(future3,
(result2, result3) -> "任务4:组合结果 -> " + result2 + ",长度加倍后:" + result3);
// 5. 多任务并行执行(等待所有任务完成)
CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2, future3);
allFutures.thenRun(() -> System.out.println("所有任务执行完毕!"));
// 6. 异常处理
CompletableFuture<Integer> future5 = CompletableFuture.supplyAsync(() -> {
if (true) {
throw new RuntimeException("任务5执行出错!");
}
return 100;
}).exceptionally(ex -> {
System.out.println("捕获异常:" + ex.getMessage());
return -1; // 异常时返回默认值
});
// 等待所有任务完成(实际开发中很少用get()阻塞,更多用异步回调)
try {
future5.get();
System.out.println("任务3的最终结果:" + future3.get());
System.out.println("任务4的组合结果:" + future4.get());
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
4. 回调
这种方式比较传统了,不推荐使用
java
interface Callback {
void onComplete(String result);
}
void asyncTask(Callback callback) {
new Thread(() -> {
try {
Thread.sleep(1000);
callback.onComplete("任务完成");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
// 调用
asyncTask(result -> {
System.out.println("回调结果:" + result);
});
改用下面的
kotlin
CompletableFuture.supplyAsync(() -> {
// 异步任务
return "任务结果";
}).thenAccept(result -> {
// 回调处理结果(非阻塞)
System.out.println("收到结果: " + result);
}).exceptionally(ex -> {
// 异常处理
ex.printStackTrace();
return null;
});
5. 响应式编程(Reactive Programming)
java
// 1. 创建一个简单的数据流(Mono - 单个元素)
Mono<String> mono = Mono.just("Hello Reactor")
.map(s -> s + "!")
.doOnNext(System.out::println);
// 2. 创建一个包含多个元素的数据流(Flux)
Flux<Integer> flux = Flux.range(1, 5)
.map(i -> i * 2)
.filter(i -> i > 5);
// 3. 异步处理示例
Flux<String> asyncFlux = Flux.just("任务1", "任务2", "任务3")
.publishOn(Schedulers.boundedElastic()) // 切换到异步线程
.map(task -> {
// 模拟耗时操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return task + " 处理完成";
});
// 4. 组合多个数据流
Flux.combineLatest(
flux.map(i -> "数字: " + i),
asyncFlux,
(numStr, taskStr) -> numStr + " - " + taskStr
).subscribe(
result -> System.out.println("组合结果: " + result), // 处理正常结果
error -> System.err.println("错误: " + error.getMessage()), // 处理错误
() -> System.out.println("所有数据处理完成") // 处理完成通知
);
// 等待异步操作完成
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
6. ### **Java 11+ 异步 HTTP 请求
适合微服务和网络请求场景
java
// 1. 创建 HttpClient 实例
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2) // 使用 HTTP/2
.connectTimeout(Duration.ofSeconds(10)) // 连接超时
.build();
// 2. 创建 GET 请求
HttpRequest getRequest = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/get"))
.timeout(Duration.ofSeconds(10))
.header("Accept", "application/json")
.GET()
.build();
// 3. 发送异步 GET 请求
CompletableFuture<HttpResponse<String>> getFuture = client.sendAsync(
getRequest,
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)
);
// 处理 GET 请求结果(非阻塞方式)
getFuture.thenAccept(response -> {
System.out.println("GET 响应状态码: " + response.statusCode());
System.out.println("GET 响应体: " + response.body().substring(0, 100) + "..."); // 打印部分内容
}).exceptionally(e -> {
System.err.println("GET 请求出错: " + e.getMessage());
return null;
});
// 4. 创建 POST 请求(带表单数据)
HttpRequest postRequest = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/post"))
.timeout(Duration.ofSeconds(10))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString("name=test&age=20"))
.build();
// 5. 发送异步 POST 请求
CompletableFuture<HttpResponse<String>> postFuture = client.sendAsync(
postRequest,
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)
);
// 处理 POST 请求结果(阻塞方式获取,仅作示例)
HttpResponse<String> postResponse = null;
try {
postResponse = postFuture.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
System.out.println("\nPOST 响应状态码: " + postResponse.statusCode());
System.out.println("POST 响应体: " + postResponse.body().substring(0, 100) + "...");
// 等待所有异步操作完成
CompletableFuture.allOf(getFuture, postFuture).join();
System.out.println("\n所有请求处理完毕");
总结
方式 | 是否推荐 | 是否阻塞 | 适用场景 | 核心工具 |
---|---|---|---|---|
Thread / Runnable | ⚠️ 简单场景 | 是(需手动管理) | 简单异步任务 | Thread , Runnable |
ExecutorService + Future | ✅ 一般场景 | 获取结果是阻塞的 | 需要返回值的异步任务 | ExecutorService , Future |
CompletableFuture | ✅✅ 推荐(Java 8+) | 非阻塞 | 复杂异步逻辑、任务编排 | CompletableFuture |
回调(Callback) | ⚠️ 老代码/事件驱动 | 通常是回调形式 | 传统异步通知 | 自定义接口 |
响应式编程(Reactor/RxJava) | ✅ 高级场景 | 非阻塞 | 流式数据、高并发、WebFlux | Mono , Flux , Observable |
异步 HTTP 客户端(HttpClient) | ✅ 网络请求 | 非阻塞 | 异步网络调用 | HttpClient.sendAsync() |
Kotlin 协程(与 Java 互操作) | ✅ 简洁异步 | 非阻塞(挂起函数) | 更优雅的异步代码 | Kotlin Coroutines |