SpringBoot系统列 3 - 多线程数据处理(ThreadPoolTaskExecutor、DruidDataSource)
在上篇文章的基础上进行改造:
package com.hello.util; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component; import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future; /**
* 线程工具类
* @author XIHONGLEI
* @date 2018-11-13
*/
@Component
public class ThreadPoolUtil {
private static final Logger LOG = LoggerFactory.getLogger(ThreadPoolUtil.class); @Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor; public void executeTask(Runnable task){
threadPoolTaskExecutor.submit(task);
//try {
//注意task.get()会阻塞,直到返回数据为止,所以一般这样用法很少用
//resp = task.get();
//} catch (InterruptedException e) {
//e.printStackTrace();
//} catch (ExecutionException e) {
//e.printStackTrace();
//}
}
}
package com.hello; import com.hello.filter.ApiInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; /**
* 配置类
* @author XIHONGLEI
* @date 2018-10-31
*/
@SpringBootConfiguration
public class WebConfig extends WebMvcConfigurationSupport { @Value("${server.port}")
public String port; @Value("${threadpool.core-pool-size}")
private int corePoolSize; @Value("${threadpool.max-pool-size}")
private int maxPoolSize; @Value("${threadpool.queue-capacity}")
private int queueCapacity; @Value("${threadpool.keep-alive-seconds}")
private int keepAliveSeconds; @Override
protected void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
// 将 ApiInterceptor 拦截器类添加进去
registry.addInterceptor(new ApiInterceptor());
} @Bean(name="threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setKeepAliveSeconds(keepAliveSeconds);
// 核心线程池数
pool.setCorePoolSize(corePoolSize);
// 最大线程
pool.setMaxPoolSize(maxPoolSize);
// 队列容量
pool.setQueueCapacity(queueCapacity);
// 队列满,线程被拒绝执行策略
pool.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
return pool;
}
}
package com.hello.service.impl; import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSONArray;
import com.hello.entity.ContractDetailDto;
import com.hello.service.CheckPositionService;
import com.hello.util.ThreadPoolUtil;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List; @Service("checkPositionService")
public class CheckPositonServiceImpl implements CheckPositionService { @Autowired
private ThreadPoolUtil threadPoolUtil; private static DruidDataSource dataSourceMDB = null;
private static SqlSessionFactory sqlSessionFactory = null;
//声明Connection对象
Connection con;
//驱动程序名
String driver = "com.mysql.jdbc.Driver";
//URL指向要访问的数据库名mydata
String url = "jdbc:mysql://localhost:3306/db_hello?useUnicode=true&characterEncoding=utf8&connectTimeout=5000&socketTimeout=60000&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true";
//MySQL配置时的用户名
String user = "root";
//MySQL配置时的密码
String password = "root"; private SqlSession getSqlSession() throws Exception {
try{
if(dataSourceMDB == null || sqlSessionFactory == null){
dataSourceMDB = new DruidDataSource();
//设置连接参数
dataSourceMDB.setUrl(url);
dataSourceMDB.setDriverClassName(driver);
dataSourceMDB.setUsername(user);
dataSourceMDB.setPassword(password);
//配置初始化大小、最小、最大
dataSourceMDB.setInitialSize(10);
dataSourceMDB.setMinIdle(10);
dataSourceMDB.setMaxActive(5000);
//连接泄漏监测
//dataSourceMDB.setRemoveAbandoned(true);
//dataSourceMDB.setRemoveAbandonedTimeout(30);
//配置获取连接等待超时的时间
dataSourceMDB.setMaxWait(500000);
//配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
dataSourceMDB.setTimeBetweenEvictionRunsMillis(20000);
//防止过期
dataSourceMDB.setValidationQuery("SELECT 'x'");
dataSourceMDB.setTestWhileIdle(true);
dataSourceMDB.setTestOnBorrow(true); TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSourceMDB);
Configuration configuration = new Configuration(environment);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
return sqlSessionFactory.openSession();
}else{
return sqlSessionFactory.openSession();
}
}catch(Exception e){
throw e;
}
}
private List<ContractDetailDto> getContractDetailList(Long contId){
try{
List<ContractDetailDto> list = new ArrayList<>();
SqlSession session = getSqlSession();
con = session.getConnection();
if(!con.isClosed()){
System.out.println("Succeeded connecting to the Database!");
} String sql = "SELECT cont_detail_id,detail_start_time,detail_end_time FROM ad_contract_detail WHERE is_del=0 AND cont_id=?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setLong(1,contId);
ResultSet rs = ps.executeQuery();
while(rs.next()){
ContractDetailDto dto = new ContractDetailDto();
dto.setContDetailId(rs.getLong("cont_detail_id"));
dto.setDetailStartTime(rs.getDate("detail_start_time"));
dto.setDetailEndTime(rs.getDate("detail_end_time"));
list.add(dto);
}
rs.close();
con.close();
session.close();
return list;
} catch(Exception e) {
//数据库驱动类异常处理
System.out.println("Sorry,can`t find the Driver!");
e.printStackTrace();
}
return null;
} private List<ContractDetailDto> checkIsLock(Long contId,List<ContractDetailDto> dtoList,String threadName){
try{
SqlSession session = getSqlSession();
con = session.getConnection();
if(!con.isClosed()){
System.out.println("Succeeded connecting to the Database!");
}
List<ContractDetailDto> checkOutList = new ArrayList<>();
String sql = "SELECT ac.cont_name,ac.cont_id,ac.cont_code,acd.cont_detail_id,acdp.position_id,rp.position_name,rp.position_code " +
"FROM rs_position rp " +
"INNER JOIN ad_contract_detail_point acdp ON rp.id = acdp.position_id " +
"INNER JOIN ad_contract_detail acd ON acdp.cont_detail_id = acd.cont_detail_id " +
"INNER JOIN rs_put_plan rpp ON acd.cont_detail_id = rpp.contract_detail_id " +
"INNER JOIN ad_contract ac ON ac.cont_id = rpp.contract_id " +
"WHERE rpp.point_stauts != 1 AND acd.is_del = 0 AND ac.is_del=0 " +
"AND rpp.contract_id NOT IN (?) " +
"AND ( " +
" (acd.detail_start_time >= ? AND acd.detail_start_time <= ?) " +
" OR (acd.detail_start_time <= ? AND acd.detail_end_time >= ?) " +
" OR (acd.detail_end_time >= ? AND acd.detail_end_time <= ?) " +
") " +
"AND rp.id IN ( " +
" SELECT position_id FROM ad_contract_detail_point WHERE cont_detail_id = ? " +
")";
int i = 1;
for(ContractDetailDto dto : dtoList){
System.out.println("[".concat(threadName).concat("]正在执行第:").concat(i+"").concat("条"));
PreparedStatement ps = con.prepareStatement(sql);
ps.setLong(1,contId);
java.sql.Date sTime = new java.sql.Date(dto.getDetailStartTime().getTime());
java.sql.Date eTime = new java.sql.Date(dto.getDetailEndTime().getTime());
ps.setDate(2,sTime);
ps.setDate(3,eTime);
ps.setDate(4,sTime);
ps.setDate(5,eTime);
ps.setDate(6,sTime);
ps.setDate(7,eTime);
ps.setLong(8,dto.getContDetailId());
ResultSet rs = ps.executeQuery();
while(rs.next()){
ContractDetailDto cdDto = new ContractDetailDto();
cdDto.setContDetailId(rs.getLong("cont_detail_id"));
cdDto.setPositionId(rs.getLong("position_id"));
cdDto.setPositionCode(rs.getString("position_code"));
cdDto.setPositionName(rs.getString("position_name"));
cdDto.setContId(rs.getLong("cont_id"));
cdDto.setContName(rs.getString("cont_name"));
cdDto.setContCode(rs.getString("cont_code"));
checkOutList.add(cdDto);
}
i+=1;
rs.getStatement().close();
rs.close();
ps.close();
}
con.close();
session.close();
return checkOutList;
} catch(Exception e) {
//数据库驱动类异常处理
System.out.println("Sorry,can`t find the Driver!");
e.printStackTrace();
}
return null;
} @Override
public void checkPosition(Long contId) {
List<ContractDetailDto> detailDtoList = this.getContractDetailList(contId);
if(detailDtoList != null && detailDtoList.size() > 0){
List<ContractDetailDto> threadList1 = new ArrayList<>();
List<ContractDetailDto> threadList2 = new ArrayList<>();
List<ContractDetailDto> threadList3 = new ArrayList<>();
if(detailDtoList.size() <= 3){
threadList1.addAll(detailDtoList);
}else{
int stepLen = detailDtoList.size() / 3;
int i = 1;
for(ContractDetailDto dto : detailDtoList){
if(i <= stepLen){
threadList1.add(dto);
}else if(i> stepLen && i <= stepLen * 2){
threadList2.add(dto);
}else{
threadList3.add(dto);
}
i += 1;
}
}
if(threadList1.size() > 0){
Runnable runnable = () ->{
List<ContractDetailDto> checkOutList = this.checkIsLock(contId,threadList1,"线程1");
try {
System.out.println("[线程1]最后结果是:");
JSONArray array = new JSONArray();
for(ContractDetailDto dto : checkOutList){
if(dto.getPositionId() != null && dto.getPositionId() != 0) {
array.add(dto.toJsonString());
}
}
System.out.println(array);
}catch (Exception e){
e.printStackTrace();
}
};
threadPoolUtil.executeTask(runnable);
}
if(threadList2.size() > 0){
Runnable runnable = () ->{
List<ContractDetailDto> checkOutList = this.checkIsLock(contId,threadList2,"线程2");
try {
System.out.println("[线程2]最后结果是:");
JSONArray array = new JSONArray();
for(ContractDetailDto dto : checkOutList){
if(dto.getPositionId() != null && dto.getPositionId() != 0) {
array.add(dto.toJsonString());
}
}
System.out.println(array);
}catch (Exception e){
e.printStackTrace();
}
};
threadPoolUtil.executeTask(runnable);
}
if(threadList3.size() > 0){
Runnable runnable = () ->{
List<ContractDetailDto> checkOutList = this.checkIsLock(contId,threadList2,"线程3");
try {
System.out.println("[线程3]最后结果是:");
JSONArray array = new JSONArray();
for(ContractDetailDto dto : checkOutList){
if(dto.getPositionId() != null && dto.getPositionId() != 0) {
array.add(dto.toJsonString());
}
}
System.out.println(array);
}catch (Exception e){
e.printStackTrace();
}
};
threadPoolUtil.executeTask(runnable);
}
}
}
}
SpringBoot系统列 3 - 多线程数据处理(ThreadPoolTaskExecutor、DruidDataSource)的更多相关文章
- SpringBoot系统列 2 - 配置文件,多环境配置(dev,qa,online)
实现项目的多环境配置的方法有很多,比如通过在Pom.xml中配置profiles(最常见) 然后在Install项目打War包的时候,根据需求打不同环境的包,如图: 这种配置多环境的方法在SSM框架中 ...
- SpringBoot系统列 1 - HelloWorld!
学习SpringBoot系统列之HelloWorld! 1.新建一个Maven项目 2.添加POM配置 <parent> <groupId>org.springframewor ...
- SpringBoot系统列 4 - 常用注解、拦截器、异常处理
在前面代码基础上进行改造: 1.SpringBoot常用注解 @SpringBootApplication :指定SpringBoot项目启动的入口,是一个复合注解,由@Configuration.@ ...
- SpringBoot系统列 5 - 接口版本控制、SpringBoot FreeMarker模板引擎
接着上篇博客的代码继续写 1.接口版本控制 一个系统上线后会不断迭代更新,需求也会不断变化,有可能接口的参数也会发生变化,如果在原有的参数上直接修改,可能会影响线上系统的正常运行,这时我们就需要设置不 ...
- Postgresql的隐藏系统列
转自 https://www.2cto.com/database/201206/137301.html Postgresql的隐藏系统列 和oracle数据库一样,postgresql也有自身 ...
- ASP.Net:Javascript 通过PageMethods 调用后端WebMethod方法 + 多线程数据处理 示例
ASP.Net:Javascript 通过PageMethods 调用后端WebMethod方法 + 多线程数据处理 示例 2012年04月27日 16:59:16 奋斗的小壁虎 阅读数:4500 ...
- Java进阶专题(十三) 从电商系统角度研究多线程(上)
前言 本章节主要分享下,多线程并发在电商系统下的应用.主要从以下几个方面深入:线程相关的基础理论和工具.多线程程序下的性能调优和电商场景下多线程的使用. 多线程J·U·C 线程池 概念 回顾线程创 ...
- Java进阶专题(十五) 从电商系统角度研究多线程(下)
前言 本章节继上章节继续梳理:线程相关的基础理论和工具.多线程程序下的性能调优和电商场景下多线程的使用. 多线程J·U·C ThreadLocal 概念 ThreadLocal类并不是用来解决 ...
- Bootstrap3 栅格系统-列排序
通过使用 .col-md-push-* 和 .col-md-pull-* 类就可以很容易的改变列(column)的顺序. <div class="row"> <d ...
随机推荐
- python序列类型字符串的方法L.index()与L.find()区别
首先官方解释 S.index(sub[, start[, end]]) -> int Like S.find() but raise ValueError when the substring ...
- JS引用类型之Array
ECMAScript中的数组可以说是比较神奇了, ECMAScript中定义的数组每一项可以保存不同的数据类型,如第一项为字符串,第二项为数值等等 1. 那怎么创建一个数组呢? 方法和创建对象实例类似 ...
- List集合的总结和应用场景的介绍
1.List的整体介绍 List 是一个接口,它继承于Collection的接口,它代表着有序的队列.list的实现类对象中每一个元素都有一个索引值,能够按照索引值进行元素查找. AbstractLi ...
- 25条div+CSS编程提醒及小技巧整理
1.ul标签在Mozilla中默认是有padding值的,而在IE中只有margin有值. 2.同一个的class选择符可以在一个文档中重复出现,而id选择符却只能出现一次:对一个标签同时使用clas ...
- Vue(十七)模块化开发
模块化开发 使用vue-cli创建项目 1. vue-router模块化 引入vue-router cnpm install vue-router -S 1.1 编辑main.js imp ...
- Mac添加自定义启动图标到Launchpad
1.使用Automator进行录制 2.选择Application 3.使用运行shell脚本 4.保存在应用程序 5.效果 参考: https://apple.stackexchange.com/q ...
- Java Web 清除缓存
res.setHeader("Cache-Control", "no-cache"); res.setHeader("Pragma", &q ...
- 一些mysql小技巧总结
1.mysql中不清除表里的数据重新设置自增的id的方法 设置主键id自增的数据库表删除数据后,自增id不会自动重新计算,想要重新设置自增的id可以用如下命令: alter table table_n ...
- Gradle sync failed: /Applications/Android Studio.app/Contents/gradle/gradle-2.14.1/lib/plugins/gradle-diagnostics-2.14.1.jar (No such file or directory) Consult IDE log for more details (Help | Sh
上面出现的错误是,我从Android Studio 2.2 升级到2.3后,出现的问题, 找到方法: http://stackoverflow.com/questions/30526613/andro ...
- 对Rethinking ImageNet Pre-training的理解
Kaiming He的这篇论文提出了一个新问题,在目标检测.实例分割和人体关键点检测等领域,预训练的模型是否真的起了作用?通过实验,得出结论:迭代次数较少时,使用预训练模型效果更好:但是只要迭代次数充 ...