面试题答案
一键面试1. 异常处理对线程资源使用效率的影响
在高并发场景下,CompletableFuture 的异常处理如果不当,可能导致线程资源不能及时释放,例如在 exceptionally
等方法中如果处理逻辑复杂且阻塞,会使持有线程的任务长时间不结束,影响线程的复用,进而影响整体效率。另外,频繁创建新线程处理异常也会带来不必要的开销。
2. 优化线程资源使用及避免线程泄漏的方法
- 使用线程池:通过自定义线程池来执行 CompletableFuture 的任务。线程池可以控制线程的数量,避免线程无限制创建。例如:
ExecutorService executor = Executors.newFixedThreadPool(10);
CompletableFuture.supplyAsync(() -> {
// 异步任务逻辑
return result;
}, executor)
.thenApplyAsync(result -> {
// 后续处理逻辑
return processedResult;
}, executor)
.exceptionally(ex -> {
// 异常处理逻辑
return null;
});
- 异常处理策略:
- 统一异常处理:在整个异步任务链的最后统一处理异常,避免在中间环节重复处理,减少不必要的线程开销。例如:
CompletableFuture.supplyAsync(() -> {
if (condition) {
throw new RuntimeException("自定义异常");
}
return "正常结果";
})
.thenApplyAsync(result -> {
// 对结果进行处理
return processedResult;
})
.exceptionally(ex -> {
// 统一处理异常
System.err.println("捕获异常: " + ex.getMessage());
return null;
});
- **快速失败**:如果某个异步任务依赖的前置任务失败,后续依赖该任务结果的任务应快速失败,避免不必要的计算。可以使用 `whenComplete` 方法结合 `isCompletedExceptionally` 来实现:
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
if (condition) {
throw new RuntimeException("任务1失败");
}
return "任务1结果";
});
CompletableFuture<String> future2 = future1.thenApplyAsync(result -> {
// 基于任务1结果处理任务2
return "任务2结果";
});
future2.whenComplete((result, ex) -> {
if (ex != null) {
// 任务2快速失败处理
System.err.println("任务2快速失败: " + ex.getMessage());
} else {
// 正常处理结果
}
});
3. 实际应用场景示例(大型分布式系统的异步任务处理)
假设在一个大型分布式系统中,有一个订单处理流程,涉及多个异步任务,如库存检查、支付处理、订单记录等。
// 创建线程池
ExecutorService orderExecutor = Executors.newFixedThreadPool(20);
// 库存检查任务
CompletableFuture<Boolean> inventoryCheck = CompletableFuture.supplyAsync(() -> {
// 模拟库存检查逻辑
boolean hasStock = checkInventory();
if (!hasStock) {
throw new RuntimeException("库存不足");
}
return true;
}, orderExecutor);
// 支付处理任务,依赖库存检查结果
CompletableFuture<Boolean> paymentProcess = inventoryCheck.thenApplyAsync(stockResult -> {
if (stockResult) {
// 模拟支付处理逻辑
return processPayment();
}
return false;
}, orderExecutor);
// 订单记录任务,依赖支付处理结果
CompletableFuture<Void> orderRecord = paymentProcess.thenAcceptAsync(paymentResult -> {
if (paymentResult) {
// 模拟订单记录逻辑
recordOrder();
}
}, orderExecutor);
// 统一异常处理
orderRecord.exceptionally(ex -> {
// 处理整个订单流程中的异常
System.err.println("订单处理异常: " + ex.getMessage());
return null;
});
通过以上方式,在大型分布式系统的异步任务处理中,结合线程池和合适的异常处理策略,能高效处理 CompletableFuture 异常,同时优化线程资源使用,避免线程泄漏和不必要的线程开销。