关于Java中单线程处理数据过慢的问题解决

有个需求调用了外部接口查询客户的违章信息,一共一千多辆车,查看日志的时候这段程序居然跑了有半个多小时。

之前的处理逻辑是将所有的数据遍历,根据客户的车辆信息一个个去调用接口。

这么长时间,肯定要优化。想了想:可以将查出来的所有数据分片,分n片,启动n个线程,分别去执行查接口的功能。由于公司使用的服务器一般四核cpu,所以使用可以将数据分成8片,并启动8个线程。(一个并发程序开多少线程合适?

 

一、首先是启动8个线程,这里使用了JUC的线程池。

有一篇专门介绍创建线程池的方法:《Java ExecutorService四种线程池的例子与说明》

二、然后将数据分片

之前也专门写过一个文章,可以出门左拐,这里就不详细介绍了。 ==》List分片处理

三、处理数据

 

由于是单机程序,是将所有的数据查出来,然后分片处理,所以不会出现各种并发类型问题。但是还是有一个小小的问题,之前计算这段程序的处理时间失效了。原因是之前用主线程记录时间,程序也跑在主线程上,所以只需要在程序的前后new 两个时间,计算差值就可以了。现在使用子线程处理数据后,这样处理就不可以了。

之前处理运行时间的逻辑:

@RequestMapping("send-break-rules-msg")
    public void sendMsgToClient() {
        Date startDate = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.info("<<<<<<<<<<<<<<<send break rules msg start at:{}>>>>>>>>>>>>>>", sdf.format(startDate));

        // 从数据库查数据

        // ......

        // 查询外部接口,处理数据       

        Date endDate = new Date();
        log.info("<<<<<<<<<<<<<<<send break rules msg end at:{}>>>>>>>>>>>>>>", sdf.format(endDate));
        log.info("<<<<<<<<<<<<<<<send break rules msg cost:{}>>>>>>>>>>>>>>", endDate.getTime() - startDate.getTime());
    }

在主线程中使用CountDownLatch工具类,在每个子线程的处理逻辑最后加上 countDownLatch.countDown();

经过这样的处理之后,这段程序完美的别控制在了5分钟以内。

猜你喜欢

转载自blog.csdn.net/Asa_Prince/article/details/85257666
今日推荐