CompletableFuture异常优雅处理方式

CompletableFuture是Java 8提供了新特性,实现了CompletionStage接口和Future接口,增加了异步回调、流式处理、多个Future组合处理的能力。可以帮助我们简化异步编程的复杂性,让我们在Java在处理多任务的协同工作时更加顺畅便利。以下是记录一次使用CompletableFuture优化业务代码的技巧。

  • 需求场景:

业务有一接口获取数据,数据需要在一个for loop中查询的数据,每个查询都是独立的互不影响,而且不能使用批量查询。当有一个查询抛出正常的业务异常时,直接把异常抛出无需继续往下查询。如果每一查询成功,则返回一个结果list。

  • 方案梳理
    • for loop下逐个查询,时间复杂度时O(n);
    • for loop增加线程池处理,理想的时间复杂度是O(1);

明显使用线程池可以提升查询响应时间,值得注意是这里是要求有返回结果的。我们可以使用future.get()来阻塞获取线程池的结果包括异常。

但是,仅仅通过future.get()来获取结果就很容踩到一些坑的:

  1. future.get()获取的异常经过包裹,很难区分出业务正常抛出的异常;
  2. for loop下future.get(),需要阻塞等等所有线程执行完毕,没有很好满足单一线程抛出业务异常就返回结果。

下面就使用CompletableFuture来优化for loop下线程池处理业务以及异常的处理方法。

  • 方法前准备

    线程池executor、resultList(并发下注意使用安全容器)、futureList

private static final ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("my-pool-%d").get();
private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100), threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
// private static final List<Integer> resultList = new ArrayList<>();
private static final List<Integer> resultList = Collections.synchronizedList(new ArrayList<>());
private static final List<CompletableFuture<Integer>> futureList = new ArrayList<>();
  • 测试方法

记录方法执行时间和异常发生的时间

public static void main(String[] args) {
   
    long start = System.currentTimeMillis();
    try {
   
        doSomething(executor, resultList, futureList);
    } catch (Exception e) {
   
        System.out.println("main 处理了异常 -> " + e.getMessage());
    }
    System.out.println("方法执行时间: " + (System.currentTimeMillis() - start)
  • 0
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值