理解CompletableFuture的非阻塞
非阻塞是指程序在执行某个操作时,不会因为等待该操作完成而停止执行后续代码,而是可以继续处理其他任务。在 Java 并发编程中,CompletableFuture
通过回调机制和异步执行实现了非阻塞的特性。以下是具体体现非阻塞的方式:
1. 回调机制
CompletableFuture
提供了丰富的回调方法(如 thenApply
、thenAccept
、thenRun
等),可以在任务完成后自动触发回调函数,而无需阻塞主线程等待任务完成。
示例:
CompletableFuture.supplyAsync(() -> {
// 模拟耗时任务
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello";
}).thenAccept(result -> {
// 非阻塞处理结果
System.out.println("Result: " + result);
});
System.out.println("Main thread continues to run...");
输出:
Main thread continues to run...
Result: Hello
说明:
supplyAsync
启动了一个异步任务。thenAccept
注册了一个回调函数,在任务完成后自动执行。- 主线程不会阻塞,而是继续执行后续代码(打印
"Main thread continues to run..."
)。
2. 异步执行
CompletableFuture
的任务默认在 ForkJoinPool
或指定的线程池中异步执行,主线程不会被阻塞。
示例:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 模拟耗时任务
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Async Task Completed";
});
System.out.println("Main thread is not blocked.");
输出:
Main thread is not blocked.
说明:
- 异步任务在后台线程中执行,主线程不会被阻塞,可以继续执行其他代码。
3. 组合多个异步任务
CompletableFuture
支持将多个异步任务组合在一起,任务之间可以并行执行,主线程不会被阻塞。
示例:
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Task 1";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Task 2";
});
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2);
combinedFuture.thenRun(() -> {
System.out.println("All tasks completed.");
});
System.out.println("Main thread continues to run...");
输出:
Main thread continues to run...
All tasks completed.
说明:
future1
和future2
并行执行,主线程不会被阻塞。thenRun
在所有任务完成后触发回调。
4. 异常处理的非阻塞
CompletableFuture
提供了 exceptionally
和 handle
等方法,可以在任务发生异常时非阻塞地处理异常。
示例:
CompletableFuture.supplyAsync(() -> {
if (true) {
throw new RuntimeException("Task failed!");
}
return "Success";
}).exceptionally(ex -> {
System.out.println("Exception: " + ex.getMessage());
return "Fallback Result";
}).thenAccept(result -> {
System.out.println("Final Result: " + result);
});
System.out.println("Main thread continues to run...");
输出:
Main thread continues to run...
Exception: Task failed!
Final Result: Fallback Result
说明:
- 任务抛出异常后,
exceptionally
非阻塞地处理异常并返回备用结果。 - 主线程不会被阻塞,继续执行后续代码。
总结
CompletableFuture
通过以下方式体现非阻塞:
- 回调机制:任务完成后自动触发回调,无需阻塞主线程。
- 异步执行:任务在后台线程中执行,主线程可以继续运行。
- 任务组合:多个任务可以并行执行,主线程不会被阻塞。
- 异常处理:异常发生时,非阻塞地处理异常并返回备用结果。
这些特性使得 CompletableFuture
成为处理异步任务的强大工具,能够显著提升程序的并发性能和响应速度。