- 由于网络上大多是对线程池使用的简介,包括书本都是非常有限的知识,所以记录个人在工作中结合线程池使用的实践。
- 业务场景为:
- 原因:查询多天的交易数据过慢(数据量过大+无法走索引+全表扫描)
- 思路1:分割发送的日期,将一次查询转化为多次查询,最后合并结果集
- 问题:在发送日期间隔较长时会创建较多的线程(实测newFixThreadPool的工作线程为10),可能会大量占用数据库连接池
- 思路2:跑定时任务,将每天的交易数据汇总到一张新表中,查询走新表,由于汇总数据所占空间比全量交易小的多,所以查询会快的多
- 问题:无法说服leader。。。
- 使用:
1.接收传入的时间,计算出其时间间隔,按天分割为dao查询所需要的格式
2.创建Callable的类,在run方法实际执行dao,所需要的参数通过构造方法传入
3.在service中将Callable类对象放到Callable的list中,交给线程池执行
4.使用Future接收Callable的返回值,其中get为阻塞的
5.将需要group by的key和接收的List以key-value的形式放到一个Map中进行合并
6.业务操作,累加交易金额
PS:构造方法传参实际为线程不安全的,后面的线程会将之前的数据覆盖,在此处通过ConcurrentHashMap实现线程安全
- 自评:
- 使用简陋,本想一起使用countDownLatch,不知道是不会用还是其他,发现并不需要用到countDownLatch即可实现
- try-catch包裹混乱