Java使用多线程异步执行批量更新操作
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils; import java.util.List; /**
* 拆分结合工具类
*
* @author shiwen
* @date 2020/12/27
*/
public class SplitListUtils { /**
* 拆分集合
*
* @param <T> 泛型对象
* @param resList 需要拆分的集合
* @param subListLength 每个子集合的元素个数
* @return 返回拆分后的各个集合组成的列表
* 代码里面用到了guava和common的结合工具类
**/
public static <T> List<List<T>> split(List<T> resList, int subListLength) {
if (CollectionUtils.isEmpty(resList) || subListLength <= 0) {
return Lists.newArrayList();
}
List<List<T>> ret = Lists.newArrayList();
int size = resList.size();
if (size <= subListLength) {
// 数据量不足 subListLength 指定的大小
ret.add(resList);
} else {
int pre = size / subListLength;
int last = size % subListLength;
// 前面pre个集合,每个大小都是 subListLength 个元素
for (int i = 0; i < pre; i++) {
List<T> itemList = Lists.newArrayList();
for (int j = 0; j < subListLength; j++) {
itemList.add(resList.get(i * subListLength + j));
}
ret.add(itemList);
}
// last的进行处理
if (last > 0) {
List<T> itemList = Lists.newArrayList();
for (int i = 0; i < last; i++) {
itemList.add(resList.get(pre * subListLength + i));
}
ret.add(itemList);
}
}
return ret;
} // 运行代码
public static void main(String[] args) {
List<String> list = Lists.newArrayList();
int size = 1099;
for (int i = 0; i < size; i++) {
list.add("hello-" + i);
}
// 大集合里面包含多个小集合
List<List<String>> temps = split(list, 100);
int j = 0;
// 对大集合里面的每一个小集合进行操作
for (List<String> obj : temps) {
System.out.println(String.format("row:%s -> size:%s,data:%s", ++j, obj.size(), obj));
}
} }
public void threadMethod() {
List<T> updateList = new ArrayList();
// 初始化线程池, 参数一定要一定要一定要调好!!!!
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(20, 50,
4, TimeUnit.SECONDS, new ArrayBlockingQueue(10), new ThreadPoolExecutor.AbortPolicy());
// 大集合拆分成N个小集合, 这里集合的size可以稍微小一些(这里我用100刚刚好), 以保证多线程异步执行, 过大容易回到单线程
List<T> splitNList = SplitListUtils.split(totalList, 100);
// 记录单个任务的执行次数
CountDownLatch countDownLatch = new CountDownLatch(splitNList.size());
// 对拆分的集合进行批量处理, 先拆分的集合, 再多线程执行
for (List<T> singleList : splitNList) {
// 线程池执行
threadPool.execute(new Thread(new Runnable(){
@Override
public void run() {
for (Entity yangshiwen : singleList) {
// 将每一个对象进行数据封装, 并添加到一个用于存储更新数据的list
// ......
// 任务个数 - 1, 直至为0时唤醒await()
countDownLatch.countDown();
}
}
}));
}
try {
// 让当前线程处于阻塞状态,直到锁存器计数为零
countDownLatch.await();
} catch (InterruptedException e) {
throw new BusinessLogException(ResponseEnum.FAIL);
}
// 通过mybatis的批量插入的方式来进行数据的插入, 这一步还是要做判空
if (GeneralUtil.listNotNull(updateList)) {
batchUpdateEntity(updateList);
LogUtil.info("xxxxxxxxxxxxxxx");
}
}
CountDownLatch概念
CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)。
CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成一些任务,然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务。
CountDownLatch的用法
CountDownLatch典型用法:1、某一线程在开始运行前等待n个线程执行完毕。将CountDownLatch的计数器初始化为new CountDownLatch(n),每当一个任务线程执行完毕,就将计数器减1 countdownLatch.countDown(),当计数器的值变为0时,在CountDownLatch上await()的线程就会被唤醒。一个典型应用场景就是启动一个服务时,主线程需要等待多个组件加载完毕,之后再继续执行。
CountDownLatch典型用法:2、实现多个线程开始执行任务的最大并行性。注意是并行性,不是并发,强调的是多个线程在某一时刻同时开始执行。类似于赛跑,将多个线程放到起点,等待发令枪响,然后同时开跑。做法是初始化一个共享的CountDownLatch(1),将其计算器初始化为1,多个线程在开始执行任务前首先countdownlatch.await(),当主线程调用countDown()时,计数器变为0,多个线程同时被唤醒。
Java使用多线程异步执行批量更新操作的更多相关文章
- 吴裕雄--天生自然JAVA数据库编程:执行数据库更新操作
import java.sql.Connection ; import java.sql.DriverManager ; import java.sql.Statement ; public clas ...
- mybatis执行批量更新update
Mybatis的批量插入这里有http://ljhzzyx.blog.163.com/blog/static/38380312201353536375/.目前想批量更新,如果update的值是相同的话 ...
- mysql批量update更新,mybatis中批量更新操作
在日常开发中,有时候会遇到批量更新操作,这时候最普通的写法就是循环遍历,然后一条一条地进行update操作.但是不管是在服务端进行遍历,还是在sql代码中进行遍历,都很耗费资源,而且性能比较差,容易造 ...
- JDBC操作,执行数据库更新操作
目标: 使用Connection对象取得Statement实例 使用Statement进行数据增删改. Statement接口 要对数据库操作,要使用Statement完成.此接口可以使用Connec ...
- 如何 ︰ 执行批量更新和插入使用.NET 提供程序在 C#.NET OpenXML
https://support.microsoft.com/zh-cn/kb/315968 如何 ︰ 执行批量更新和插入使用.NET 提供程序在 C#.NET OpenXML Email Prin ...
- mybatis 的批量更新操作sql
转: mybatis 的批量更新操作sql 2018年07月23日 10:38:19 海力布 阅读数:1689 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...
- mongodb批量更新操作文档的数组键
persons文档的数据如下: > db.persons.find(){ "_id" : 2, "name" : 2 }{ "_id" ...
- Spring源码分析——JdbcTemplate执行批量insert操作
最近用到一个方法: @Override public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss) thr ...
- Mybatis之批量更新操作
更新单条记录 UPDATE course SET name = 'course1' WHERE id = 'id1'; 更新多条记录的同一个字段为同一个值 UPDATE course SET name ...
随机推荐
- Java IO模型:BIO、NIO、AIO
Java IO模型:BIO.NIO.AIO 本来是打算直接学习网络框架Netty的,但是先补充了一下自己对Java 几种IO模型的学习和理解.分别是 BIO.NIO.AIO三种IO模型. IO模型的基 ...
- 添加删除系统右键菜单(就是上下文菜单,也就是Context Menu)中的一些选项
随着电脑安装的东西越来越多,右侧菜单也原来越长,很不方面.所以打算清理一下 我删除的大约以下几个,友好一点的都可以配置.当然也可以通过注册表直接删除. 特:注册表备份,即导入导出,避免一失足成千古恨. ...
- Visual Studio Code 配置C、C++ 文件debug调试环境
目录 vscode C/C++ Extension Pack 插件安装 vscode windows 端 debug 配置 window MinGW 环境安装 windows 端 C.CPP 单文件 ...
- Python中编码encode()与解码decode()
1 print('这是编码'.encode('utf-8')) # 结果 b'\xe8\xbf\x99\xe6\x98\xaf\xe7\xbc\x96\xe7\xa0\x81' 2 print('这是 ...
- 2022李宏毅作业hw1—新冠阳性人员数量预测。
事前 : kaggle地址:ML2021Spring-hw1 | Kaggle 我的git地址: https://github.com/xiaolilaoli/lihongyi2022homew ...
- 替代Tableau,思迈特软件Smartbi让Excel成为企业级自助分析平台
谈到企业级自助分析平台,大家自然会想到Tableau,在Garnter最新的BI平台魔力象限中,是这么描述Tableau的. "Tableau is a Leader in this ...
- 不知道这10个术语,你还敢说会JavaScript?
每个行业,都有业内"行话",不了解这些行话的人,很难融入到行业中,也永远装不了逼. 从Curry到Closes,有很多JavaScript行话(该领域中使用的特殊词汇)知道这些行话 ...
- C# 使用NPOI处理Excel模板-【前面部分固定,中间是动态的几行,尾部是固定的部分】
今天同组的兄弟问我,他有一个导出的模板,大概如下: [前面部分固定,中间是动态的几行,尾部是固定的部分].其实这个很像单链表往单链表在指定插入数据. 他问我怎么做才好,他想到的做法是:因为这些动态列的 ...
- 使用Xshell连接VMware上的Linux虚拟机
转至:https://www.cnblogs.com/yenengfeng/p/13684265.html 虚拟机自己安装好,这边直接说步骤.有借鉴这篇文章 https://www.cnblogs.c ...
- Android系统编程入门系列之硬件交互——无线通信WLAN
Android系统的移动设备大多支持无线WLAN技术.利用该技术,不仅能实现互联网通信,还能实现无线定位,热点共享等远程通信功能.针对使用WLAN的不同功能,可能需要分别申请不同的权限声明,同时调用不 ...