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

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

     private void batchDeal(List data, int batchNum) throws InterruptedException {
int totalNum = data.size();
int pageNum = totalNum % batchNum == 0 ? totalNum / batchNum : totalNum / batchNum + 1;
ExecutorService executor = Executors.newFixedThreadPool(pageNum);
5 try {
CountDownLatch countDownLatch = new CountDownLatch(pageNum);
List subData = null;
int fromIndex, toIndex;
for (int i = 0; i < pageNum; i++) {
fromIndex = i * batchNum;
toIndex = Math.min(totalNum, fromIndex + batchNum);
subData = data.subList(fromIndex, toIndex);
ImportTask task = new ImportTask(subData, countDownLatch);
executor.execute(task);
}
// 主线程必须在启动其它线程后立即调用CountDownLatch.await()方法,
// 这样主线程的操作就会在这个方法上阻塞,直到其它线程完成各自的任务。
// 计数器的值等于0时,主线程就能通过await()方法恢复执行自己的任务。
countDownLatch.await();
logger.info("数据操作完成!可以在此开始其它业务");
} finally {
// 关闭线程池,释放资源
executor.shutdown();
}
} class ImportTask implements Runnable {
private List list;
private CountDownLatch countDownLatch; public ImportTask(List data, CountDownLatch countDownLatch) {
this.list = data;
this.countDownLatch = countDownLatch;
} @Override
public void run() {
if (null != list) {
// 业务逻辑,例如批量insert或者update
logger.info("现在操作的数据是{}", list);
}
// 发出线程任务完成的信号
countDownLatch.countDown();
}
}

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

Java 使用线程池分批插入或者更新数据的更多相关文章

  1. Java进阶——— 线程池的原理分析

    前言 在了解线程池之前,其实首先出现的疑问是:为什么要使用线程池,其次是了解什么是线程池,最后是如何使用线程池,带着疑问去学习. 为什么要使用 前面多线程文章中,需要使用线程就开启一个新线程,简单方便 ...

  2. 线程池;java的线程池的实现原理;适用于频繁互动(如电商网站)

    线程池是一种多线程处理形式,处理过程中将任务加入到队列,然后在创建线程后自己主动启动这些任务.线程池线程都是后台线程.每一个线程都使用默认的堆栈大小,以默认的优先级执行.并处于多线程单元中. 假设某个 ...

  3. 谈谈Java的线程池设计

    在实际项目中,如果因为想异步执行暂时性的任务而不断创建线程是很浪费资源的事情(当一个任务执行完后,线程也没用了).这种情况下,最好是将任务提交给线程池执行. 所谓池,就是将管理某一种资源,对资源进行复 ...

  4. [Java多线程]-线程池的基本使用和部分源码解析(创建,执行原理)

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 多线 ...

  5. 深入理解Java之线程池

    原作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...

  6. Java中线程池的学习

    线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程 ...

  7. java利用线程池处理集合

    java利用线程池处理集合 2018年07月23日 17:21:19 衍夏成歌 阅读数:866   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/s ...

  8. 深入理解Java之线程池(爱奇艺面试)

    爱奇艺的面试官问 (1) 线程池是如何关闭的 (2) 如何确定线程池的数量 一.线程池销毁,停止线程池 ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown() ...

  9. Java中线程池,你真的会用吗?

    在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...

随机推荐

  1. [转载]详解网络传输中的三张表,MAC地址表、ARP缓存表以及路由表

    [转载]详解网络传输中的三张表,MAC地址表.ARP缓存表以及路由表 虽然学过了计算机网络,但是这部分还是有点乱.正好在网上看到了一篇文章,讲的很透彻,转载过来康康. 本文出自 "邓奇的Bl ...

  2. 恺撒密码 B

    恺撒密码 B ‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭ ...

  3. nlopt 二次优化

    /* * main.c * * Created on: Oct 9, 2018 * Author: lgh */ #include <stdio.h> #include <math. ...

  4. VisualSVN 关于权限(第1篇)

    总结权限的规则: 1.子目录权限完全覆盖父目录权限.以子目录的权限为最终.仓库本身就是祖宗,所有的子目录继承他的权限,所有仓库本身必须增加可访问权限,要么everyone ,要么增加全部团队成员. 2 ...

  5. 安卓直连SQLSEVER数据库

    1.导入连接SQLSEVER的jar包:可以支持android的SQL驱动(如:jtds-1.2.7.jar) 2.编写连接数据库的工具类 import java.lang.reflect.Field ...

  6. prometheus 配置项注意事项

    1.job:metrics_path 如果是静态模式下配置job(statics),直接配置job的metrics_path选项是不生效的.需要同时在exporter端指定metrics_path.如 ...

  7. PAT Basic 1050 螺旋矩阵 (25 分)

    本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”.所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充.要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N:m ...

  8. python:pycharm中使用pandas读取中文路径报错问题的解决方案

    假如你的文件路径名是这样的,例如:test.csv 只要它是小文件(大文件采用分块读取,后续会补上文件分块读取的相关博客),你的内存扛得住,那就直接 import pandas as pd test ...

  9. mysql全量和增量备份详解(带脚本)

    在日常运维工作中,对mysql数据库的备份是万分重要的,以防在数据库表丢失或损坏情况出现,可以及时恢复数据. 下面对这种备份方案详细说明下:1.MySQLdump增量备份配置执行增量备份的前提条件是M ...

  10. go语言合并两个数组

    https://stackoverflow.com/questions/16248241/concatenate-two-slices-in-go Add dots after the second ...