线程池使用、countDownLatch、以及数据库批量插入 添加配置优化插入与计算
//新建线程池
ThreadPoolExecutor cpuThreadPoolExecutor = ThreadUtil.getCpuThreadPoolExecutor();
//使用CountdoLatch
final CountDownLatch countDownLatch = new CountDownLatch((int) (selectIpInfoParam.getIpValue2() - selectIpInfoParam.getIpValue1() + 1));
//循环的时候使用线程池执行
for (long i = selectIpInfoParam.getIpValue1(); i <= selectIpInfoParam.getIpValue2(); i++) {
Ip finalIp = ip;
long finalI = i;
cpuThreadPoolExecutor.execute(() -> {
getIpDetail(finalIp, ipDetails, item00, item01, netType, finalI, map);
countDownLatch.countDown();
});
}
try {
//使用countdoLatch 来停顿主线程,直到数值达到零为止
countDownLatch.await();
if (!CollectionUtils.isEmpty(ipDetails)) {
//批量保存可以设置每次存储更多,默认是1000
ipDetailService.saveBatch(ipDetails, 10000);
}
} catch (Exception e) {
throw new ApiException(500, "服务异常!");
}
&rewriteBatchedStatements=true :设置在数据库连接后面,可以使保存批量更快速
public final class ThreadUtil {
private ThreadUtil() {
}
/**
* 最大线程上并非越大越快,别瞎整,需要实际调试
*/
private static final int MAX_THREAD_COUNT = 15;
/**
* CPU 数量
*/
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
public static <T> ThreadPoolExecutor getIOThreadPoolExecutor() {
return getThreadPoolExecutor(CPU_COUNT << 4, CPU_COUNT << 5, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), Executors.defaultThreadFactory());
}
public static <T> ThreadPoolExecutor getCpuThreadPoolExecutor() {
return getThreadPoolExecutor(CPU_COUNT + 1, CPU_COUNT *2, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), Executors.defaultThreadFactory());
}
private static <T> ThreadPoolExecutor getThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit timeUnit, BlockingQueue<Runnable> queue, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, queue, threadFactory);
}
public static <T> void execute(ThreadPoolExecutor poolExecutor, Collection<T> collection, Consumer<T> consumer, int threadCount) {
// 空集合
if (CollectionUtils.isEmpty(collection)) {
return;
}
// 处理数量小于等于2 不开启子线程
if (collection.size() <= 2) {
collection.forEach(consumer);
return;
}
// 将request设置为子线程共享
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
CountDownLatch countDownLatch = new CountDownLatch(threadCount);
BlockingQueue<T> queue = new LinkedBlockingQueue<>(collection);
for (int a = 0; a < threadCount; a++) {
poolExecutor.execute(() -> {
try {
RequestContextHolder.setRequestAttributes(sra);
while (true) {
T t = queue.poll();
if (null == t) {
break;
}
consumer.accept(t);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
RequestContextHolder.resetRequestAttributes();
countDownLatch.countDown();
}
});
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static <T> void execute(ThreadPoolExecutor poolExecutor, Collection<T> collection, Consumer<T> consumer) {
// 启用线程数量
int threadCount = Math.min((collection.size() >>> 1) + 1, MAX_THREAD_COUNT);
execute(poolExecutor, collection, consumer, threadCount);
}
}
线程池使用、countDownLatch、以及数据库批量插入 添加配置优化插入与计算的更多相关文章
- jsp采用数据库连接池的方法获取数据库时间戳context.xml配置,jsp页面把时间格式化成自己需要的格式
<?xml version="1.0" encoding="UTF-8"?> <!-- 数据库连接池配置文件 --> <Conte ...
- 基于SmartThreadPool线程池技术实现多任务批量处理
一.多线程技术应用场景介绍 本期同样带给大家分享的是阿笨在实际工作中遇到的真实业务场景,请跟随阿笨的视角去如何采用基于开源组件SmartThreadPool线程池技术实现多任务批量处理.在工作中您是否 ...
- Android(java)学习笔记267:Android线程池形态
1. 线程池简介 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...
- 线程池 队列 synchronized
线程池 BlockingQueue synchronized volatile 本章从线程池到阻塞队列BlockingQueue.从BlockingQueue到synchronized 和 volat ...
- Java 线程池(ThreadPoolExecutor)原理分析与使用
在我们的开发中"池"的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 使用线程池的好处 1.降低资源消耗 可以重复利用 ...
- 从线程池到synchronized关键字详解
线程池 BlockingQueue synchronized volatile 前段时间看了一篇关于"一名3年工作经验的程序员应该具备的技能"文章,倍受打击.很多熟悉而又陌生的知识 ...
- JAVA线程池的实际运用
线程池的创建 我们可以通过ThreadPoolExecutor来创建一个线程池 /** * @param corePoolSize 线程池基本大小,核心线程池大小,活动线程小于corePoolSize ...
- 论如何优雅的自定义ThreadPoolExecutor线程池
更好的markDown阅读体验可直接访问我的CSDN博客:https://blog.csdn.net/u012881584/article/details/85221635 前言 线程池想必大家也都用 ...
- Java线程池(ThreadPoolExecutor)原理分析与使用
在我们的开发中"池"的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 使用线程池的好处 1.降低资源消耗 可以重复利用 ...
- Java并发(四)线程池使用
上一篇博文介绍了线程池的实现原理,现在介绍如何使用线程池. 目录 一.创建线程池 二.向线程池提交任务 三.关闭线程池 四.合理配置线程池 五.线程池的监控 线程池创建规范 一.创建线程池 我们可以通 ...
随机推荐
- gitee上传VS2022已有项目
1.在gitee上新建仓库: 2.复制新建仓库地址: 3.用VS2022打开先有项目,找到Git更改项: 4.点击创建Git存储库: 5.创建本地仓库并推送到远程,点击创建并推送: 6.等待创建成功即 ...
- 晓晓---python文件的读写模式的理解
1. python读取文件模式的自我理解:'r' open for reading (default)----只读模式打开文件,不能写:'w' open for writing, truncating ...
- uniapp获取本机所有应用包名
huoqu(e){ uni.showLoading({ title: '获取中' }); const main = plus.android.runtimeMainActivity(); let pM ...
- POWER BI - 根据条件,改变数值的颜色Conditional formatting
在visual块,右键Column选择Conditional formatting 举例,比如difference > 0 显示红色,否则<0显示绿色 如何根据 measure 写特定条件 ...
- guide, manual, tutorial之间的区别
总结:一般而言,guide表示用户指南,提供简要的信息:manual表示用户手册,提供较为完整深入的说明:tutorial表示教程,提供详细的说明,侧重于给没有经验的人一步一步进行详细的指导.实际情况 ...
- 时间函数strtotime的强大
转载:php的strtotime举例-lsstarboy-ChinaUnix博客 1.上周日午夜 strtotime("last sunday"); 2.本周日午夜 strt ...
- rust crm 镜像源管理
一.下载crm cargo install crm https://github.com/wtklbm/crm 二.命令 # 在终端执行 # # NOTE: # - [args] 表示 args 是一 ...
- HELM的使用
一.helm的主要功能 1.创建新的chart 2.chart打包成tgz格式 3.上传chart到chart仓库或从仓库中下载chart 4.在kubernetes集群中安装或卸载chart 5.管 ...
- docker持久化数据存储
一.把数据存储到本地/opt/data目录下面,容器挂载到/data目录下面 [root@docker-1 ~]# docker run -itd --name www -v /opt/data:/d ...
- 前端电商 sku 的全排列算法
需求 需求描述起来很简单,有这样三个数组: let names = ["iPhone",'iPhone xs'] let colors = ['黑色','白色'] let stor ...