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 ...
随机推荐
- phpstorm连接ftp
1.先到服务器中添加一个专门连接ftp的账号 useradd --help useradd -c sftp -d /data/project/testdir/ -g root -M sftp // 创 ...
- Class "xxxxx"defined without specifying a base class
解决方法: 导入#import xxxx.h即可 程序需要了解整个类.所以需要添加 #import xxxx.h
- C/JS_二分法查找
1. 二分法查找 前提: 数据是排好序的. 题设:给出一个有序arr,从中找出key,arr的区间是array[ low , higt]. 步骤: (1)mid=(low+high)/2 (2)arr ...
- Vue(二十三)vuex + axios + 缓存 运用 (以登陆功能为例)
(一)axios 封装 (1)axios拦截器 可以在axios中加入加载的代码... (2)封装请求 后期每个请求接口都可以写在这个里面... (二)vuex user.js import { lo ...
- pygame 笔记-9 图片旋转及边界反弹
h5或flash中,可以直接对矢量对象,比如line, rectange旋转,但是pygame中,仅支持对image旋转,本以为这个是很简单的事情,但是发现还是有很多小猫腻的,记录一下: 先看一个错误 ...
- shell之磁盘容量检查,配合crontab可以定时清理磁盘
我的做法: !/bin/bashAvailable=`df -k | sed -n 2p | awk '{print $4}'`if [ $Available -eq 0 ];then ...
- .net core日志记录
.net core日志记录 日志是必须的,目前采用log4net进行日志记录. 定义通用的日志记录方法 public static class Log4NetFunc { private static ...
- 经纬度编码方法推荐-plus code简介
今天罗孚为大家推荐一种经纬度编码的方法--plus code,原名open location code,是Google于2014年发明的,旨在将表示地理位置的经纬度通过算法推导成一个字符串. plus ...
- ESP-EYE V2.1 开发板 WINDOWS 10 开发入门
准备工作 1 × ESP-EYE V2.1 开发板 1 × Micro USB B 电缆 1 × PC(Windows10) 简介 ESP-EYE 是一款面向人脸识别和语音识别市场的开发板,搭载 ES ...
- python读取excel(xlrd)
一.安装xlrd模块: 1.mac下打开终端输入命令: pip install xlrd 2.验证安装是否成功: 在mac终端输入 python 进入python环境 然后输入 import xl ...