57000+单词原始录入时间258S
核心代码:
List<Word> wordBookList = ExcelUtil.getReader(file.getInputStream()).readAll(Word.class);if (!CollectionUtil.isEmpty(wordBookList)) {for (Word word : wordBookList) {//逐条向数据库中插入单词wordMapper.insert(word);}}
线程池方式录入时间18S
核心代码:
//获取核心数int coreCount = Runtime.getRuntime().availableProcessors();//创建线程池ExecutorService executorService= Executors.newFixedThreadPool(2*coreCount);List<Word> wordBookList = ExcelUtil.getReader(file.getInputStream()).readAll(Word.class);//对列表单词进行分区并发录入int partitionSize=wordBookList.size()/(2*coreCount);List<List<Word>> wordListPartition = Lists.partition(wordBookList, partitionSize);for (int i = 0; i <wordListPartition.size(); i++) {Runnable task=new ExcelInput(wordListPartition.get(i),wordMapper);executorService.execute(task);}executorService.shutdown();//阻塞当前线程,直到线程池中的任务执行完毕try {if(!executorService.awaitTermination(1, TimeUnit.HOURS)){executorService.shutdownNow();}} catch (InterruptedException e) {e.printStackTrace();Thread.currentThread().interrupt();}
优化流程:
首先获取当前主机核心数N,因为大数据量单词录入属于IO密集型所以我们设置线程池的大小为2*N第二步我选择将List拆分为2*N接着放入线程池当中去执行单词录入任务基于此线程池中的多个线程可以对数据的录入进行并发操作大大提高了录入的效率
选择2*N的原因是代码中获取的核心数为物理核心数,而实际上主机可以利用超线程技术将一个物理核心当做两个逻辑核心来使用,当我们想让CPU利用率达到100%时就可以设置2*N个线程数并将单词分为2*N份交给线程池中的线程处理同时减少了线程的上下文切换所带来的损耗。
240/258=0.93
优化后单词录入效率提高90%以上