newFixedThreadPool线程池实现多线程
List<PackageAgreementEntity> entityList = new CopyOnWriteArrayList<>();
//多线程 10个线程
//int threadNum = 10;
int listSize = 300;
List<List<PackageAgreementDto>> splitData = Lists.partition(packageAgreementList, listSize);
//CountDownLatch latch = new CountDownLatch(splitData.size());
//声明线程池对象
ExecutorService touchWorker = Executors.newFixedThreadPool(splitData.size());
//不加这个会导致线程不安全,丢失数据
Semaphore semaphore = new Semaphore(splitData.size());//定义几个许可
List<PackageAgreementErroDto> errorList2 = new CopyOnWriteArrayList();
for (int i = 0; i < packageAgreementList.size(); i++) {
final int j = i;
semaphore.acquire();
touchWorker.execute(()->{
try {
logger.info(Thread.currentThread().getName()+ j);
logger.info("数据第几条:" + j);
//校验物料、供应商、ou、地点信息是否存在
packageAgreementService.checkMultiData(packageAgreementList.get(j), j ,user, dateFormat, errorList2, entityList);
semaphore.release();
} catch (ParseException e) {
e.printStackTrace();
}
});
}
//每隔10s检测线程是否执行结束
boolean flag = touchWorker.awaitTermination(10, TimeUnit.SECONDS);
if(!flag){
logger.info("一揽子协议价格录入完成!");
}
需要注意的问题点,多线程处理List数据可能发生线程不安全,
引入CopyOnWriteArrayList,Semaphore解决,或者加锁解决问题;所有线程执行完毕后再进行后续业务的处理,引入awaitTermination()方法。