CompleteableFutrue 实现多线程返回不阻塞

一、用线程池的时候用Future来接收实现了Callable的线程实现类的返回值,应用如下

     /**
     * 下单线程实现类
     */
    class OrderCallable implements Callable<List<OrderInfo>> {

        private List<OrderInfo> orderInfos;
        private UserDTO user;

        OrderCallable(List<OrderInfo> orderInfos, UserDTO user) {
            this.orderInfos = orderInfos;
            this.user = user;
        }

        @Override
        public List<OrderInfo> call() {

            List<OrderInfo> rs = new ArrayList<>();

            for (OrderInfo orderInfo : orderInfos) {
                logger.info("开始下单:{}", orderInfo.getOrderId());
                orderInfo = orderDifferentService(orderInfo, user);
                rs.add(orderInfo);
                logger.info("下单返回:{}, {}", orderInfo.getOrderId(), orderInfo.getOrderState());
            }
            return rs;
        }

    }

二、线程池调用

     /**
     * 后台批量下单才启用线程池,接口无须开启
     */
    private List<OrderInfo> syncOrderWithThreadPool(List<OrderInfo> orderInfos, UserDTO user) {

        List<List<OrderInfo>> orderLists = Lists.partition(orderInfos, 50);

        List<OrderInfo> rsList = CollUtil.newArrayList();

        orderLists.stream().forEach(orderList -> {
            Future<List<OrderInfo>> futureRs = executorService.submit(new OrderCallable(orderList, user));
            try {
                List<OrderInfo> getList = futureRs.get();
                rsList.addAll(getList);
            } catch (Exception e) {
                logger.error("future get is Error: {}", e);
            }
        });

        return rsList;
    }

三、get()方法可以当任务结束后返回一个结果,如果调用时,工作还没有结束,则会阻塞线程,直到任务执行完毕,因此看似开启了多线程,实际上还是在循环的时候进行了阻塞,和串行的效率是一样的

四、改动,使用Jdk1.8 Future的新实现类 CompletableFuture,有合并方法,也可以通过线程池初始化并通过继承Supplier获取返回值,改动如下

     /**
     * 下单线程实现类
     */
    class OrderCallable implements Supplier<List<OrderInfo>> {

        private List<OrderInfo> orderInfos;
        private UserDTO user;

        OrderCallable(List<OrderInfo> orderInfos, UserDTO user) {
            this.orderInfos = orderInfos;
            this.user = user;
        }

        @Override
        public List<OrderInfo> get() {

            List<OrderInfo> rs = new ArrayList<>();

            for (OrderInfo orderInfo : orderInfos) {
                logger.info("开始下单:{}", orderInfo.getOrderId());
                orderInfo = orderDifferentService(orderInfo, user);
                rs.add(orderInfo);
                logger.info("下单返回:{}, {}", orderInfo.getOrderId(), orderInfo.getOrderState());
            }
            return rs;
        }

    }

调用

    /**
     * 后台批量下单才启用线程池,接口无须开启
     */
    private List<OrderInfo> syncOrderWithThreadPool(List<OrderInfo> orderInfos, UserDTO user) {

        List<List<OrderInfo>> orderLists = Lists.partition(orderInfos, 100);

        List<OrderInfo> rsList = CollUtil.newArrayList();

        List<CompletableFuture<List<OrderInfo>>> futures = new ArrayList<>();

        orderLists.forEach(orderInfoModelList ->
                futures.add(CompletableFuture.supplyAsync(new OrderCallable(orderInfoModelList, user),
                        executorService)));
        // 合并
        CompletableFuture<Void> all = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
        // 阻塞,直到所有的任务执行结束(等待最长的任务)
        all.join();
        try {
            for (CompletableFuture future : futures) {
                List<OrderInfo> getList = (List<OrderInfo>) future.get();
                rsList.addAll(getList);
            }
        } catch (Exception e) {
            logger.error("获取future返回值异常1", e);
        }
        return rsList;
    }

五、使用CompletableFuture 的静态方法 allOf、anyOf可以根据需求合并想要的多线程结果,做到真正的并发。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值