Java 使用线程池分批插入或者更新数据
需求:在开发业务报表时,需要从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 使用线程池分批插入或者更新数据的更多相关文章
- Java进阶——— 线程池的原理分析
前言 在了解线程池之前,其实首先出现的疑问是:为什么要使用线程池,其次是了解什么是线程池,最后是如何使用线程池,带着疑问去学习. 为什么要使用 前面多线程文章中,需要使用线程就开启一个新线程,简单方便 ...
- 线程池;java的线程池的实现原理;适用于频繁互动(如电商网站)
线程池是一种多线程处理形式,处理过程中将任务加入到队列,然后在创建线程后自己主动启动这些任务.线程池线程都是后台线程.每一个线程都使用默认的堆栈大小,以默认的优先级执行.并处于多线程单元中. 假设某个 ...
- 谈谈Java的线程池设计
在实际项目中,如果因为想异步执行暂时性的任务而不断创建线程是很浪费资源的事情(当一个任务执行完后,线程也没用了).这种情况下,最好是将任务提交给线程池执行. 所谓池,就是将管理某一种资源,对资源进行复 ...
- [Java多线程]-线程池的基本使用和部分源码解析(创建,执行原理)
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 多线 ...
- 深入理解Java之线程池
原作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...
- Java中线程池的学习
线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程 ...
- java利用线程池处理集合
java利用线程池处理集合 2018年07月23日 17:21:19 衍夏成歌 阅读数:866 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/s ...
- 深入理解Java之线程池(爱奇艺面试)
爱奇艺的面试官问 (1) 线程池是如何关闭的 (2) 如何确定线程池的数量 一.线程池销毁,停止线程池 ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown() ...
- Java中线程池,你真的会用吗?
在<深入源码分析Java线程池的实现原理>这篇文章中,我们介绍过了Java中线程池的常见用法以及基本原理. 在文中有这样一段描述: 可以通过Executors静态工厂构建线程池,但一般不建 ...
随机推荐
- (七)装配Bean(1)
针对给接口提供哪一个具体的实现,也就是装配哪一种具体的实现bean,在Spring中提供了多种方式,主要包括3种: 一.隐式的bean发现机制和自动装配(自动化装配bean) 二.在Java类中进行显 ...
- C#工厂模式案例
class JianDanGongChang { static void Main(string[] args) { Factory factory=new LianXiangFactory(); D ...
- 1 vue 关键字解释
1 每一个计算属性都包含一个getter和一个setter,计算属性可以依赖其他计算属性,计算属性可以依赖当前vue实例的数据也可以依赖其他vue实例的数据 2 计算属性是基于它的依赖缓存的,方法则是 ...
- FPGA上外挂DDR2&DDR3&MIG IP的使用记录
前言 当需要大容量数据存储及处理的时候,FPGA内部自带的存储资源是远远不够的,所以问题来了,怎么使用外带的DDR3? 首要问题在于DDR3是什么?有没有协议?当然只是需要用Xilinx MIG IP ...
- 2.Java集合-ConcurrentHashMap实现原理及源码分析
一.为何用ConcurrentHashMap 在并发编程中使用HashMap可能会导致死循环,而使用线程安全的HashTable效率又低下. 线程不安全的HashMap 在多线程环境下,使用HashM ...
- selenium网页截图和截图定位(无界面)phantomjs
phantomjs是一款软件,需要重新安装. 参考: https://blog.csdn.net/liyahui_3163/article/details/79064108 案例代码: from se ...
- sh make.sh fatal error: opencv2/opencv.hpp: No such file or directory
问题: sh make.sh fatal error: opencv2/opencv.hpp: No such file or directory 解决: sudo apt-get install l ...
- C++ 输出PPM格式图片文件
PPM简介 学习图形学时为了直观地观察结果,需要输出图片,而PPM是一种最简单的图片格式,非常适合新手使用. PPM文件的内容大概是这样的: 第一行固定为P3,代表写入的是PPM格式的RGB图像,除此 ...
- Kostya the Sculptor(贪心
这题本来 想二分.想了很久很久,解决不了排序和二分的冲突. 用贪心吧.. 题意: 给你n个长方形,让你找出2个或1个长方体,使得他们拼接成的长方体的内接球半径最大(这是要求最短边越大越好)( ...
- Python基础之While循环
一.摘要 本片博文将介绍input()函数和while循环的使用 二.input()函数 函数input() 让程序暂停运行,等待用户输入一些文本.获取用户输入后,Python将其存储在一个变量中,以 ...