并发执行查询汇总返回结果集

68 篇文章 0 订阅
25 篇文章 0 订阅

需求: 做数据统计,但是有的sql执行太慢。然后优化添加索引,再用线程池去执行各自sql。汇总结果集

需要注意下:每次异步执行需要创建一个新对象,不要复用对象。get()得方法就有阻塞等待线程处理完成得效果。做到最后数据都能拿到。


import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.*;

/**
 * @author xyd
 * @description:
 * @date 2020/3/23
 */
public class demo {

    /**
     * 获取基本信息
     *
     * @return
     */
    public static String getProductBaseInfo(String productId) {
        return productId + "商品基础信息";
    }

    /**
     * 获取详情信息
     *
     * @return
     */
    public static String getProductDetailInfo(String productId) throws InterruptedException {
        Thread.sleep(20000L);
        return productId + "商品详情信息";
    }

    /**
     * 获取sku信息
     *
     * @return
     */
    public static String getProductSkuInfo(String productId) throws InterruptedException {
        Thread.sleep(10000L);
        return productId + "商品sku信息";
    }


    /**
     * 取得一个商品的所有信息(基础、详情、sku)
     *
     * @param productId
     * @return
     */
    public static String getAllInfoByProductId(String productId) {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> getProductBaseInfo(productId), executor);
        CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> {
            try {
                return getProductDetailInfo(productId);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }, executor);
        CompletableFuture<String> f3 = CompletableFuture.supplyAsync(() -> {
            try {
                return getProductSkuInfo(productId);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }, executor);

        try {
            String baseInfo = f1.get();
            String detailInfo = f2.get();
            String skuInfo = f3.get();
            return baseInfo + "" + detailInfo + skuInfo;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(getAllInfoByProductId("xyd"));
    }
}
runAsync 没有返回值

supplyAsync  需要返回值

多线程异步求同一个接口时。 

 private static void batchGenTableRecord(JudgeComponentFetchLogicBO logic, Map<String, Object> baseInfo,
            Map<String, Object> extraInfo, Map<String, Object> dataSourceValue, List<Integer> indexList,
            Map<Integer, List<ComponentViewRecordBO>> vMap, Map<String, List<Map>> sourceMap) {
        CompletableFuture<Void> all = CompletableFuture.allOf(
                indexList.stream().map(index -> CompletableFuture.supplyAsync(() -> {
                    genTableRecord(logic, baseInfo, extraInfo, dataSourceValue, index, vMap, sourceMap);
                    return vMap;
                }, ThreadPoolUtil.COMPONENT_POOL).exceptionally(e -> {
                    log.error("asyncGenTableComponentData error: {}", e.getMessage());
                    return vMap;
                })).toArray(CompletableFuture[]::new));
        //阻塞,直到所有任务结束。
        all.join();
    }
public QueueGatherResultBO queryJudgeQueueGatherListByStaff(String staff) {
        if (StringUtils.isBlank(staff)) {
            throw JudgeException.of(ErrorCode.PARAM_INVALID);
        }
        QueueGatherResultBO result = new QueueGatherResultBO();
        //1.获取用户绑定的队列集
        List<Long> gatherIds = orgStructureService.queryGatherListByStaff(staff);
        log.info("queryJudgeQueueGatherListByStaff.queryGatherListByStaff.result:{}",
                JsonMapperUtils.toJson(gatherIds));
        if (CollectionUtils.isEmpty(gatherIds)) {
            return result;
        }

        //2。查询每个队列集详情信息
        //队列集信息获取(队列id对应队列的名称,kconf维护的)
        List<QueueGatherConf> resList = ThemisJudgeJsonListConfigKey.queueGatherList.getList();
        Map<Long, String> queueGatherMap =
                resList.stream().collect(Collectors.toMap(QueueGatherConf::getId, QueueGatherConf::getName));

        CopyOnWriteArrayList<QueueGatherBO> queueGatherList = new CopyOnWriteArrayList<>();
        CopyOnWriteArrayList<GatherQueueListBO> queueGatherAllList = new CopyOnWriteArrayList<>();
        //多线程查询每个队列集下,队列列表信息(队列集绑定队列)
        CompletableFuture<Void> all = CompletableFuture.allOf(
                gatherIds.stream().map(n -> CompletableFuture.runAsync(() -> {
                    List<GatherQueueListBO> queueList = this.queryJudgeQueueListByGatherId(staff, n);
                    log.info("queryJudgeQueueGatherListByStaff.queryJudgeQueueListByGatherId.result:{}",
                            JsonMapperUtils.toJson(queueList));
                    if (!CollectionUtils.isEmpty(queueList)) {
                        //聚合待审核数量
                        int waitNumber = queueList.stream().mapToInt(GatherQueueListBO::getWaitNumber).sum();
                        //聚合已进审数量
                        int reviceeNumber = queueList.stream().mapToInt(GatherQueueListBO::getReviewedNumber).sum();
                        QueueGatherBO build =
                                QueueGatherBO.builder().gatherId(Math.toIntExact(n)).gatherName(queueGatherMap.get(n))
                                        .reviewedNumber(reviceeNumber)
                                        .waitNumber(waitNumber).build();
                        queueGatherList.add(build);
                        queueGatherAllList.addAll(queueList);
                    }
                }, ThreadPoolUtil.COMPONENT_POOL).exceptionally(e -> {
                    log.error("asyncGenTableComponentData error: {}", e.getMessage());
                    throw JudgeException.of(ErrorCode.SYSTEM_ERROR.getCode(), "获取队列集数据失败");
                    //不用异常  就return null;
                })).toArray(CompletableFuture[]::new));
        //阻塞,直到所有任务结束。
        all.join();

        //3。封装结果
        List<GatherQueueListBO> collect = queueGatherAllList.stream().distinct().collect(Collectors.toList());
        int reviewedSum = collect.stream().mapToInt(GatherQueueListBO::getReviewedNumber).sum();
        int waitSum = collect.stream().mapToInt(GatherQueueListBO::getWaitNumber).sum();
        QueueGatherBO allData =
                QueueGatherBO.builder().reviewedNumber(reviewedSum).waitNumber(waitSum).gatherId(0).gatherName("全部")
                        .build();
        result.setQueueGatherList(queueGatherList);
        result.setQueueGatherAll(allData);
        return result;
    }

并行执行调用做数据聚合

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值