做一个导入功能,用ThreadPoolExecutor 进行多线程导入10000条数据,10个线程,一个线程任务每次处理100条数据。 结果只有9000+数据正常入库,添加数据的业务没报错。查日志后发现,每页开始导入的日志有100条,但每页结束的日志只有90多。感觉有部分线程在执行任务时没有执行到最后就消失了。
问:为什么线程会执行到一半消失,后台没报错日志。怎么避免这种情况?
/**
* rowList 中有一万条学生数据
* 用多线程入库,每100条为一页,一页数据一个线程执行
*/
public void import(List<List<String>> rowList){
Integer page = total/100;
if ((total%100)>0){
page=page+1;
}
LinkedBlockingQueue linkedBlockingQueue = new LinkedBlockingQueue();
//初始化线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10,10,60, TimeUnit.SECONDS,linkedBlockingQueue);
try {
//计数分页数据
for(int i=0 ;i<page;i++){
int start = i*100;
int end = start+100;
if (end>rowList.size()){
end = rowList.size();
//分页数据
List<List<String>> lists =rowList.subList(start,end);
ImportStu importStu = new ImportStu(lists,i);
//执行线程
threadPoolExecutor.execute(importStu);
}
}catch (Exception e){
log.error("学生导入线程池执行出错:{}",e.getMessage(),e);
}
threadPoolExecutor.shutdown();
}
/**
*线程执行的任务,数据入库
*/
class ImportStu implements Runnable{
private List<List<String>> lists;
private String page;
public ImportStu(List<List<String>> rowList,int page){
this.lists = rowList;
this.page = page;
}
@Override
public void run() {
log.info("学生导入,第{}页开始导入,Thread:{}",page,Thread.currentThread().getId())
for(int i=0;i<lists.size(); i++ ){
try{
log.info("学生导入,开始执行第{}页第{}行,Thread:{}",page,i,Thread.currentThread().getId());
//单条数据入库业务
stuService.add(lists.get(i));
}catch (Exception e){
log.error("添加数据失败:{}",e.getMessage(),e);
}
}
}
log.info("学生导入,第{}页导入完毕,Thread:{}",page,Thread.currentThread().getId())
}