• Java 使用线程池分批插入或者更新数据


      需求:在开发业务报表时,需要从MySQL数据库读取数据后进行操作,然后写入数据库,使用定时任务跑批。

      分析:①兼顾性能,②  MySQL没有Oracle那么方便、强大的存储过程。综上所述,使用线程池以分批提交的方案来插入MySQL数据库,对于更新操作、在Java端进行分页等的操作,本方案也支持。代码如下:

     1     private void batchDeal(List data, int batchNum) throws InterruptedException {
     2         int totalNum = data.size();
     3         int pageNum = totalNum % batchNum == 0 ? totalNum / batchNum : totalNum / batchNum + 1;
     4         ExecutorService executor = Executors.newFixedThreadPool(pageNum); 
    5
    try { 6 CountDownLatch countDownLatch = new CountDownLatch(pageNum); 7 List subData = null; 8 int fromIndex, toIndex; 9 for (int i = 0; i < pageNum; i++) { 10 fromIndex = i * batchNum; 11 toIndex = Math.min(totalNum, fromIndex + batchNum); 12 subData = data.subList(fromIndex, toIndex); 13 ImportTask task = new ImportTask(subData, countDownLatch); 14 executor.execute(task); 15 } 16 // 主线程必须在启动其它线程后立即调用CountDownLatch.await()方法, 17 // 这样主线程的操作就会在这个方法上阻塞,直到其它线程完成各自的任务。 18 // 计数器的值等于0时,主线程就能通过await()方法恢复执行自己的任务。 19 countDownLatch.await(); 20 logger.info("数据操作完成!可以在此开始其它业务"); 21 } finally { 22 // 关闭线程池,释放资源 23 executor.shutdown(); 24 } 25 } 26 27 class ImportTask implements Runnable { 28 private List list; 29 private CountDownLatch countDownLatch; 30 31 public ImportTask(List data, CountDownLatch countDownLatch) { 32 this.list = data; 33 this.countDownLatch = countDownLatch; 34 } 35 36 @Override 37 public void run() { 38 if (null != list) { 39 // 业务逻辑,例如批量insert或者update 40 logger.info("现在操作的数据是{}", list); 41 } 42 // 发出线程任务完成的信号 43 countDownLatch.countDown(); 44 } 45 }

      在第1行中,List data表示传入的数据,batchNum表示每一次处理的数量,例如500条等。

  • 相关阅读:
    Spring AOP
    编写jQuery插件
    Linux下SVN服务器搭建
    Redis安装配置与Jedis访问数据库
    使用redis做mysql缓存
    $(document).ready(function(){})和$(window).load(function(){})的区别
    SSH三大框架简介
    docker inspect命令
    ELK 环境搭建3-Logstash
    ELK 环境搭建2-Kibana
  • 原文地址:https://www.cnblogs.com/east7/p/10953113.html
Copyright © 2020-2023  润新知