前言:
多线程,这个高端的词汇在上周真的是令我头大不已。
工作中有一个场景:每5分钟查询出待同步的订单,然后进行相关同步操作(涉及到5张表的字段修改)。
第一版方案:
1、
在项目里创建一个核心线程数为10的周期线程池。
2、
然后通过@Scheduled注释来周期性执行的执行任务
3、
自我评价:很完美。
QA提问题:由于某种原因一个线程在5分钟内没有执行完成该任务,那么另一个线程又进来了,通过查询数据库得到待同步订单,那么这两个线程这时候所持有的未处理订单是相同的,这个时候一条订单就会通过两个线程处理两次。
第二版方案:
1、
不再通过定时周期性的处理任务,而是采取——如果查询数据库的订单表中无待处理订单,那么主线程睡眠指定时间。
2、
将一次性查询到的待处理订单交给ForkJoinPool线程池中的线程处理。
ForkJoinPool线程池的特点:将提交进来的任务不断二分,直到分成小于自己指定的粒度,创建一个线程完成指定粒度那么大的任务。(上图中我所指定的粒度是8)
3、
为了保证主线程在ForkJoinPool线程池的子线程处理完提交的任务后再继续执行,这里使用到了CountDownLatch。
4、
考虑到线程安全,这里用到了可重入锁:ReentrantLo