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 ...
随机推荐
- Dell Venue 8 Pro启动盘UEFI模式32位启动,备份系统
进入微PE工具箱官方下载页面:http://www.wepe.com.cn/download.html,选择Win8PE 32位 V1.2版下载. 或者直接百度盘下载:https://pan.baid ...
- Jupyter Notebook 介绍 安装和使用技巧
Jupyter Notebook介绍.安装及使用教程 原文链接:https://www.jianshu.com/p/91365f343585 目录一.什么是Jupyter Notebook? 1. 简 ...
- 4989: [Usaco2017 Feb]Why Did the Cow Cross the Road
题面:4989: [Usaco2017 Feb]Why Did the Cow Cross the Road 连接 http://www.lydsy.com/JudgeOnline/problem.p ...
- list-列表练习
#list列表取值更方便灵活 列表.数组说的都是1个东西#列表中每个字符都有一个编号,就是我们说的下标,从0开始#如果你输入的下标在列表中不存在,会报下标越界的错误 1.查询user表中下标为0的记录 ...
- 关于js的函数
1.获取内容的兼容函数 /* * 一: 获取内容的兼容函数 * setText(obj, str) * 思路: * 1.首先判断浏览器: * 2.如果是IE浏览器,就用innerText: * 3.如 ...
- django之内置Admin
本篇导航: 配置路由 定制Admin Django内置的Admin是对于model中对应的数据表进行增删改查提供的组件,使用方式有: 依赖APP: django.contrib.auth django ...
- C#:前台线程后台线程
1.线程分类 线程由程序员创建,可是创建的方式不同,总体来说有两种,一种是个人构造,也就是使用thread类new线程对象创建,这一类线程是大部分程序员知道的,也叫专用线程;还有一种是由CLR创建,这 ...
- canvas/CSS仪表盘效果
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- An entry point cannot be marked with the 'async' modifier
I copied below code from this link.But when I am compiling this code I am getting an entry point can ...
- Nginx之——日志按日期分割的实现(基于CentOS操作系统)
Nginx自身是没有按日期切割日志的功能,可以用shell脚本实现.新建一个cut_log.sh, #!/bin/sh # Program: # Auto cut nginx log script. ...