多线程解决excel数据多上传问题

  excel名单人数过多,超多140000条,单个线程处理问题,已经不能满足需求,需要做多线程的优化。再一点就是多个线程导入需要给是否导入成功的标志。
  
  首先,上传excel根据业务校验excel,这个部分省略,可以查上传excel和校验的相关知识。
  其次,就是怎么将整个excel分拆成各个小的部分,然后分线程上传。

A、将excel全部加载在内存list中(batchParams)

//存储返回导入成功的条数
int countSuceeNumber=0;	
    //将全部excel记录发送多线程线程方法,批量导入数据
    	try{
    	countSuceeNumber=saveBaseInfoList(batchParams); 
        }catch(Exception e){
        	e.printStackTrace();
        }

B、定义方法,多线程将excel的数据存储起来

/**
   * 多线程批量存储数据
   * @param batchParams
   * @return
   */
  public int saveBaseInfoList(List batchParams){
	  int count=999;//根据数量确定一个线程处理多少条数据
      int listSize=batchParams.size();
      if(listSize>=1 && listSize<1000){
      	count=333;
      }else if(listSize>=1000 && listSize<10000){
      	count=1333;
      }else if(listSize>=10000 && listSize<30000){
      	count=2333;
      }else if(listSize>=30000){
      	count=3333;
      }
      //计算开启的线程数
      int runThreadSize=(listSize/count)+1;
      logger.info("开启的线程数量"+runThreadSize);
      //存放每个线程的执行数据
      List newList=null;
      //创建一个线程池,数量和开启线程数一样
      ExecutorService executor=Executors.newFixedThreadPool(runThreadSize);
      //存放返回结果集
      int successCountNumber=0;
      //定义completionService
      CompletionService<Integer> completionService=new ExecutorCompletionService<Integer>(executor);
      try{
      //循环创建线程
      for(int i=0;i<runThreadSize;i++){
    	  if((i+1)==runThreadSize){
    		  int startIndex;
    		  startIndex=(i*count);
    		  int endIndex=listSize;
    		  newList=batchParams.subList(startIndex, endIndex);
    	  }else{
    		  int startIndex=(i*count);
    		  int endIndex=((i+1)*count);
    		  newList=batchParams.subList(startIndex, endIndex);
    	  }
    	  createBatchInsertThread(completionService,newList);
      }
      //采用completionService.take(),内部维护阻塞队列,任务先完成的先获取到
      for(int i=0;i<runThreadSize;i++){
    	  Integer counts=completionService.take().get();
    	  successCountNumber+=counts;
      }
      logger.info("成功的条数"+successCountNumber);
	  }catch(Exception e){
		  e.printStackTrace();
	  }finally{
		  executor.shutdown();
	  }
      return successCountNumber;
  }

C、调用多线程的执行类

  private  Future<Integer> createBatchInsertThread(CompletionService<Integer> completionService,List newList) throws Exception{
	  BatchInsertThread batchinsertThread=new BatchInsertThread(newList);
	  @SuppressWarnings("unchecked")
	  Future<Integer> submit = completionService.submit(batchinsertThread);
	  return submit;
  }

D、callable()的具体执行类


public class BatchInsertThread implements Callable<Integer>{
	
	 
	 private BaseService baseService = (BaseService) SpringContextHolder.getApplicationContext().getBean("baseService"); 
	 private Logger logger = Logger.getLogger(getClass());
	 List list;
	
	 public BatchInsertThread(){
		 
	 }
	 
	 public BatchInsertThread(List list){
		 this.list=list;
		
	 }

	@Override
	public Integer call() throws Exception {
		try{
			 logger.info("本次导入人数的大小"+list.size());
			 baseService.batchInsert(list);
		 }catch(Exception e){
			 e.printStackTrace();
			 logger.error(e.getMessage());
		 }
		return list.size();
	}
	 
}

E、具体的业务执行类


@Service
public class BaseServiceImpl implements BaseService{

	@Resource
	private IAthleteScoreDao athleteScoreDao;
	
	@Override
	public void batchInsert(List list) throws Exception{
		 Map<String, Object>[] paramArrayOfMap=(Map[])list.toArray(new HashMap[list.size()]);
         athleteScoreDao.batchAddAthleteScore(paramArrayOfMap);
	}

}

这样整个过程执行下来,读取并把合格的excel存储起来,非常的快速。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MonkeyKing.sun

对你有帮助的话,可以打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值