面试题答案
一键面试优化性能策略
- 合理使用线程池:
- 创建自定义的
ExecutorService
线程池,根据应用的硬件资源(如CPU核心数)和业务场景来设置线程池的参数。例如,如果是CPU密集型任务,可以将核心线程数设置为CPU核心数;如果是I/O密集型任务,可以适当增加核心线程数。 - 示例代码:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
- 在
CompletableFuture
的thenAccept
方法中使用这个线程池,将任务提交到线程池中执行,避免使用默认的ForkJoinPool.commonPool()
,因为默认线程池可能在高并发场景下出现线程饥饿等问题。
CompletableFuture.supplyAsync(() -> { // 异步任务 return "result"; }, executorService)
- 创建自定义的
.thenAccept(result -> { // 处理结果 System.out.println("处理结果: " + result); }, executorService);
2. **减少任务复杂度**:
- 在`thenAccept`的回调中尽量避免复杂的计算和I/O操作,如果有复杂操作,可以考虑将其拆分到更小的任务中并行执行,或者将I/O操作进行批量处理,减少I/O的次数。
### 异常处理最佳实践
1. **使用`exceptionally`方法**:
- `CompletableFuture`提供了`exceptionally`方法来捕获异步任务中的异常。在`thenAccept`之后链式调用`exceptionally`方法,可以捕获前面异步任务执行过程中抛出的异常,并进行处理。
- 示例代码:
```java
CompletableFuture.supplyAsync(() -> {
if (Math.random() < 0.5) {
throw new RuntimeException("模拟异常");
}
return "result";
}, executorService)
.thenAccept(result -> {
System.out.println("处理结果: " + result);
}, executorService)
.exceptionally(ex -> {
System.out.println("捕获到异常: " + ex.getMessage());
return null;
});
- 确保应用不崩溃:
- 在
exceptionally
方法中,除了打印异常信息,还可以进行一些恢复操作,例如重试任务、使用默认值等,确保应用能够继续正常运行。 - 重试示例:
CompletableFuture.supplyAsync(() -> { if (Math.random() < 0.5) { throw new RuntimeException("模拟异常"); } return "result"; }, executorService)
- 在
.thenAccept(result -> { System.out.println("处理结果: " + result); }, executorService) .exceptionally(ex -> { System.out.println("捕获到异常: " + ex.getMessage()); // 重试逻辑 return CompletableFuture.supplyAsync(() -> { System.out.println("重试任务"); return "重试结果"; }, executorService).join(); });
### 完整高并发环境下代码示例
```java
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CompletableFutureExample {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
CompletableFuture.supplyAsync(() -> {
if (Math.random() < 0.5) {
throw new RuntimeException("模拟异常");
}
return "result";
}, executorService)
.thenAccept(result -> {
System.out.println("处理结果: " + result);
}, executorService)
.exceptionally(ex -> {
System.out.println("捕获到异常: " + ex.getMessage());
// 重试逻辑
return CompletableFuture.supplyAsync(() -> {
System.out.println("重试任务");
return "重试结果";
}, executorService).join();
});
executorService.shutdown();
}
}
上述代码展示了在高并发Java应用中使用CompletableFuture
的thenAccept
方法时,如何通过合理使用线程池优化性能,以及如何捕获和处理异常,确保应用在高并发环境下稳定运行。