举例:
核心线程数3,队列数10,最大核心线程数6
原理:重点:队列只是存放数据的,线程才是真正执行数据的
(队列数未满的情况下)队列里的数据会被核心线程执行完毕,(队列数已经满了的情况下)会新增核心线程数,从原来的3条增加至6条,用6条线程去处理队列里的任务,如果最大核心线程6条还不够处理数据,那么就会采取默认的拒绝策略(一般情况下,队列数和最大核心线程数默认值都是INT的最大值,不会触发拒绝策略,除非手动设置队列数和最大核心线程数的值变小才会触发))
流程:
当核心线程数有空闲线程出来时,会去队列里取数据继续执行队列里的数据,直到把队列的数据执行完毕,如果队列满了后,会触发最大线程数,这时会新增线程,并发执行数据,如果最大线程数还不够用,采取默认的拒绝策略,终止任务,并且可以指定自己需要的拒绝策略
代码示例:
public <T> void saveData(List<T> saveList, String flag) {
long start = System.currentTimeMillis();
String dynamicLog = FACE.equals(flag) ? FACE : (ON_DUTY.equals(flag) ? ON_DUTY : ALL);
log.info("插入" + dynamicLog + "考勤表数据开始时间 = " + start);
ExecutorService executorService = Executors.newFixedThreadPool(3);
Integer time = saveList.size() / 500;
time = saveList.size() % 500 > 0 ? time + 1 : time;
CountDownLatch latch = new CountDownLatch(time);
for (Integer i = 1; i <= time; i++) {
Integer begin =(i-1)*500;
Integer end = i.equals(time) ? saveList.size() : i * 500;
List<T> dataList = saveList.subList(begin, end);
executorService.execute(() -> {
try {
if (FACE.equals(flag)) {
faceAttendanceService.saveList((List<FaceAttendance>) dataList);
} else if (ON_DUTY.equals(flag)){
onDutyAttendanceService.saveList((List<OnDutyAttendance>) dataList);
} else {
centerAttendanceMonthService.saveList((List<CenterAttendanceMonth>) dataList);
}
} catch (Exception e) {
log.error("同步"+ dynamicLog +"考勤数据发生异常!", e);
} finally {
latch.countDown();
}
});
}
try {
//调用await()方法,阻塞主线程,当上述启动的5个分线程都执行完后,主线程才会被放行
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
long end= System.currentTimeMillis();
log.info("插入"+ dynamicLog +"考勤表数据结束时间 = " + end);
log.info("耗时毫秒 = " + (end - start));
}