线程池以及多线程调用案例,ExecutorService、CountDownLatch、Future、ConcurrentHashMap、Callable

需求:

多线程统计数据,需求是要将退单单据的单位分组汇总到同一个表中,因为退单的单据数量多,所以根据公司统计的时候会出现巨大的性能问题,计划使用定时任务,但是因为数据量大所以决定在晚上使用多线程方式将数据完成汇总。

处理方法:

使用多线程方法,ExecutorService线程池,CountDownLatch计算器,Future可以异步保存信息,ConcurrentHashMap不会出现多线程问题的map,Callable多线程接口。

实际代码
    @Test
    public void execute() {
        System.out.println("--------------------------------------------------------------------");
        Date start = new Date();
        //获取key信息
        List<String> dwList = queryOrgId();
        //启动线程池
        ExecutorService executorService = new ThreadPoolExecutor(10, 50, 100, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>());
        //设定一个计数器
        countDownLatch = new CountDownLatch(dwList.size());
        try {
            //多线程的hashmap
            Map<String, Future<Map<String, Object>>> futures = new ConcurrentHashMap<>();
            //对每一个数据进行处理
            for (String orgId : dwList) {
                Callable callable = new Callable() {
                    @Override
                    public Map<String, Object> call() throws Exception {
                        return getDataAndSendFile(orgId);
                    }
                };
                //可以在进行流程时候保存执行结果
                Future<Map<String, Object>> future = executorService.submit(callable);
                futures.put(orgId, future);
            }
            //计算器不为零会被阻塞
            countDownLatch.await();
            Map<String, Map<String, Object>> resultData = new ConcurrentHashMap<>();
            Iterator<Map.Entry<String, Future<Map<String, Object>>>> iterator = futures.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Future<Map<String, Object>>> entry = iterator.next();
                if (entry.getValue().isDone() && !entry.getValue().isCancelled()) {
                    resultData.put(entry.getKey(), entry.getValue().get());
                }
            }
            //执行结果
            System.out.println(resultData.toString());
        } catch (InterruptedException interruptedException) {
        } catch (ExecutionException e) {
        } finally {
            //关闭线程池
            executorService.shutdown();
            Date end = new Date();
            System.out.println("--------------------------------------------------------------------");
            System.out.println(end.getTime()-start.getTime());

        }
    }
  /**
     * @Description: 自己的业务代码
     */
    public Map<String, Object> getDataAndSendFile(String orgId) {
        Map<String, Object> map = new ConcurrentHashMap<>();
        try {
            map.put(orgId,orgId);
            //用来衬托业务流程中使用的时间
            Thread.sleep(1000);
            return map;
        } catch (Exception e) {
            map.put(orgId, "调用平衡检查接口异常:" + e.getMessage());
        } finally {
            countDownLatch.countDown();
        }
        return map;
    }

可以看一下写的具体的注释解释,大概就是自己改改线程池的属性和自己业务就可以了。
在这里插入图片描述

没有办法,多线程的话,可能会没有顺序可以后续加一个排序,时间大概是20178。

后续写一个没有使用多线程的代码

    @Test
    public void executes(){
        System.out.println("--------------------------------------------------------------------");
        Date start = new Date();
        List<String> dwList = queryOrgId();
        for (int i = 0; i < dwList.size(); i++) {
            String s = dwList.get(i);
            getDataAndSendFiles(s);
        }
        Date end = new Date();
        System.out.println("--------------------------------------------------------------------");
        System.out.println(end.getTime()-start.getTime());
    }
 /**
     * @Description: 自己的业务代码
     */
    public Map<String, Object> getDataAndSendFiles(String orgId) {
        Map<String, Object> map = new ConcurrentHashMap<>();
        try {
            map.put(orgId,orgId);
            Thread.sleep(1000);
            return map;
        } catch (Exception e) {
            map.put(orgId, "调用平衡检查接口异常:" + e.getMessage());
        }
        return map;
    }

在这里插入图片描述
经过代码的对比性能提升是很大的,希望这个例子在我后面多线程使用的起到作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

又是重名了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值