线程池使用、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并发(四)线程池使用
上一篇博文介绍了线程池的实现原理,现在介绍如何使用线程池. 目录 一.创建线程池 二.向线程池提交任务 三.关闭线程池 四.合理配置线程池 五.线程池的监控 线程池创建规范 一.创建线程池 我们可以通 ...
随机推荐
- node_modules修改?
1.直接改node_modules的内容..... 但是下次npm i之后那个包的代码又恢复原状 2.独立维护需要改的包 把需要改的包复制下来,修改,推送到npm上. 项目里用新包即可,但是增加了维护 ...
- 2021年RT-Thread开发者大会
Time:2021-12-18,地点:大中华6楼喜来登酒店 主办方: RT-Thread:寓意实时线程,瑞赛德 世界有成千上万个 RTOS(Real-time operating system,实时操 ...
- Cplex-opl解决网络路由选择和资源分配问题
安装Cplex 注意事项:全英文系统.安装路径.代码,会减少软件运行设置错误.(该软件对中文支持性不好) opl语言基础 [转载]CPLEX学习笔记二 – OPL的数据类型 - 知乎 (zhihu.c ...
- viewport适配解决方案
viewport的单位vw.vh vw.vh将viewport分成了一百份.vw即 viewport width vh即viewport height 1vw等于视图单位的1%的宽度 1vh等于视图单 ...
- unity学习笔记03-渲染管线
图形数据在GPU上经过运算处理,最后显示在显示器上的过程 游戏→图形API→cpu→(DRAW CALL)交给GPU→顶点处理→图元装配→光栅化→像素处理→缓存 减少DRAW CALL 增加性能 O ...
- pat乙级1013数素数
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> int ...
- HTML语言基本标签
创建一个HTML文档 <html></html> 设置文档标题以及其他不在WEB网页上显示的信息 <head></head> 设置文档的可见部分 < ...
- Hub
public class StreamHub : Hub { public ChannelReader<string> ReadLogStream() { var channel = Ch ...
- python的下载安装与使用
一.python解释器版本 创作者:龟叔 1.1python1.X(可忽略) 1.2python2.x python2.x的最高版本是2.7版本,现在仍然有不少企业老项目在使用2.7版本 1.3pyt ...
- 【剑指Offer】【链表】反转链表
题目:输入一个链表,反转链表后,输出新链表的表头. A:定义3个结点,pNode作移动指针,pRet作输出指针,pPrev作前驱指针 在pNode没有到达链尾之前,循环里创建pNext指针记录p ...