使用CyclicBarrier进行的多线程并发开发

3月份的时候有个这样的需求,查询出一个idList,然后再用每个id查询出很多数据,根据这些数据再查询相关数据,数据的量是相当的大,而且项目没有现配的线程池进行使用,万般无奈之下,自己写了个多线程查询库的操作,下面附源码,请广大码友指教:

Set<Map.Entry<String, List<String>>> entries = columnClassIdList.entrySet();
        final CyclicBarrier barrier = new CyclicBarrier(entries.size());
        for (Map.Entry<String, List<String>> entry : entries) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    logger.info("执行线程名称为:" + Thread.currentThread().getName());
                    try {
                        PriceColumn dbPriceColumn = priceColumnDao.getColumnByClassId(entry.getKey());
                        List<PriceItem> dbPriceItemList = priceItemDao.selectItemByColumnId(dbPriceColumn.getId());
                        ArrayList<PriceItem> priceItems = new ArrayList<>();
                        for (PriceItem i : dbPriceItemList) {
                            if (entry.getValue().contains(i.getClassId())) {
                                priceItems.add(i);
                            }
                        }

                        //设置结束时间
                        String formDateStr = null;
                        String toDateStr = null;
                        if (type == 3) {
                            formDateStr = startDateStr;
                            toDateStr = endDateStr;
                        }
                        if (type == 1) {
                            Date startDate = FormatDate.getDateByRecordCycle(Const.JL_DAY, priceItems.get(0).getEndDate());
                            //时间转化
                            formDateStr = FormatDate.dateToString(startDate, "yyyy-MM-dd");
                            toDateStr = FormatDate.dateToString(priceItems.get(0).getEndDate(), "yyyy-MM-dd");
                        }

                        //数据组装
                        List<String> priceItemIds = priceItems.stream().map(m -> m.getId()).collect(Collectors.toList());
                        Map<String, PriceItem> priceItemsMap = priceItems.stream().collect(Collectors.toMap(m -> m.getId(), m -> m));
                        //查询开始
                        List<PriceItemData> priceItemData = priceDataDao.selectHistoryData(entry.getKey(), priceItemIds, formDateStr, toDateStr);

                        ArrayList<JSONObject> jsonObjects = new ArrayList<>();
                        priceItemData.forEach(one -> {
                            PriceItem priceItem = priceItemsMap.get(one.getPriceItemId());
                            Map<String, DataAttribute> dataAttributeMap = IterUtil.fieldValueMap(priceItem.getDataAttributes(), "id");
                            JSONObject one4res = new JSONObject();
                            one4res.put("item_id", Constants.ID_CODE_JG + one.getItemClassId());
                            try {
                                one4res.put("province", areaDictDao.getProvinceByShortName(dataAttributeMap.get("30010").getValue()));
                            } catch (Exception e) {
                                logger.error(e.getMessage());
                            }
                            one4res.put("company_name", dataAttributeMap.get("30011").getValue());

                            one4res.put("standard", dataAttributeMap.get("30003").getValue());
                            one4res.put("product_name", getProduct(dataAttributeMap.get("30001")));
                            one4res.put("spec", dataAttributeMap.get("30002").getValue());
                            one4res.put("price_type", dataAttributeMap.get("30017").getValue());
                            one4res.put("price", one.getPrice());
                            String priceUnit = StrUtil.concat(true, dataAttributeMap.get("30018").getUnitpre(), "/", dataAttributeMap.get("30018").getUnitlat());
                            priceUnit = StrUtil.removeSuffix(priceUnit, "/");
                            one4res.put("price_unit", priceUnit);
                            one4res.put("datadate", one.getDataDate());
                            one4res.put("remark", one.getRemark());
                            res.add(one4res);
                        });
                    } catch (Exception e) {
                        logger.error(e.getMessage());
                    }

                    try {
                        barrier.await();//到达屏障
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

        }
        barrier.await();//阻塞当前线程直到latch中数值为零才执行
        return res;

中间逻辑很多,很复杂的构造返回,我也想写的好点,奈何领导要求这样写,没办法,我接下来把多线程单独搞出来给大家看:

Set<Map.Entry<String, List<String>>> entries = columnClassIdList.entrySet();
        final CyclicBarrier barrier = new CyclicBarrier(entries.size());
        for (Map.Entry<String, List<String>> entry : entries) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    logger.info("执行线程名称为:" + Thread.currentThread().getName());
                    try {
                        barrier.await();//到达屏障
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

        }
        barrier.await();//阻塞当前线程直到latch中数值为零才执行
        return res;

总体思维是在for循环中new线程执行,因为事先知道了for循环的长度,所以栅栏值也确定,然后开始循环,执行线程中的方法,最后不能忘记await()。

认识一下CyclicBarrier

CyclicBarrier适用于这样的情况:你希望创建一组任务,它们并行的执行工作,然后在进行下一步步骤之前等待,直至所有任务都完成,它使得所有的并行任务都将在删栏出列队,因此可以一致的向前移动。

当调用await时  指定的任务运行完后会awiat  直到最后一个线程运行完毕,才继续执行下一步动作。

通俗点讲就是一组线程相互等待,直到临界点。具体可查官方文档

写的不好,请望理解!! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值