Spring Boot实践——多线程
多线程
Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor。而实际开发中任务一般是非阻碍的,即异步的,所以我们要在配置类中通过@EnableAsync开启对异步任务的支持,并通过在实际执行的Bean的方法中使用@Async注解声明其是一个异步任务。
此外,还提供一种Java的实现方式,多种方式去尝试如何去实现多线程。
实现
一、基于Spring
1、配置类
import java.util.concurrent.Executor; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; /**
* @Description: 配置类实现AsyncConfigurer接口,并重写getAsyncExecutor方法,并返回一个ThreadPoolTaskExecutor,
* 这样我们就获得一个基于线程池TaskExecutor
* @ClassName: CustomMultiThreadingConfig
* @Author: OnlyMate
* @Date: 2018年9月21日 下午2:50:14
*/
@Configuration
@ComponentScan("com.only.mate.springboot.multithreading")
@EnableAsync//利用@EnableAsync注解开启异步任务支持
public class CustomMultiThreadingConfig implements AsyncConfigurer{ @Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
} @Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return AsyncConfigurer.super.getAsyncUncaughtExceptionHandler();
} }
2、创建线程任务
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; /**
* @Description: 创建线程任务服务
* @ClassName: CustomMultiThreadingService
* @Author: OnlyMate
* @Date: 2018年9月21日 下午3:17:57
*/
@Service
public class CustomMultiThreadingService {
private Logger logger = LoggerFactory.getLogger(CustomMultiThreadingService.class);
/**
* @Description:通过@Async注解表明该方法是一个异步方法,
* 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
* @Title: executeAysncTask1
* @Date: 2018年9月21日 下午2:54:32
* @Author: OnlyMate
* @Throws
* @param i
*/
@Async
public void executeAysncTask1(Integer i){
logger.info("CustomMultiThreadingService ==> executeAysncTask1 method: 执行异步任务{} ", i);
} /**
* @Description:通过@Async注解表明该方法是一个异步方法,
* 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
* @Title: executeAsyncTask2
* @Date: 2018年9月21日 下午2:55:04
* @Author: OnlyMate
* @Throws
* @param i
*/
@Async
public void executeAsyncTask2(Integer i){
logger.info("CustomMultiThreadingService ==> executeAsyncTask2 method: 执行异步任务{} ", i);
}
}
3、触发线程任务
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.only.mate.springboot.multithreading.CustomMultiThreadingService; /**
* @Description:自定义多线程Controller
* @ClassName: CustomMultiThreadingController
* @Author: OnlyMate
* @Date: 2018年9月21日 下午3:02:49
*/
@Controller
@RequestMapping(value="/multithreading")
public class CustomMultiThreadingController {
@Autowired
private CustomMultiThreadingService customMultiThreadingService; @ResponseBody
@RequestMapping(value="/dotask")
public String doTask() {
for (int i=0;i<10;i++){
customMultiThreadingService.executeAysncTask1(i);
customMultiThreadingService.executeAsyncTask2(i);
} return "success";
}
}
4、效果图
访问http://localhost:8088/springboot/multithreading/dotask

二、基于Java
1、异步线程调度管理器
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; /**
* @Description: 异步线程调度管理器
* @ClassName: CustomAsyncScheduler
* @Author: OnlyMate
* @Date: 2018年9月21日 下午3:25:40
*/
public class CustomAsyncScheduler {
private volatile static CustomAsyncScheduler instance;
private static ThreadPoolExecutor chnlBackendQueryPool; private CustomAsyncScheduler() {
} @SuppressWarnings({ "rawtypes", "static-access", "unchecked" })
public static CustomAsyncScheduler getInstance() {
if (instance == null) {
synchronized (CustomAsyncScheduler.class) {
if (instance == null) {
instance = new CustomAsyncScheduler(); BlockingQueue queue = new LinkedBlockingQueue();
chnlBackendQueryPool = new ThreadPoolExecutor(50, 100, 30, TimeUnit.SECONDS, queue);
chnlBackendQueryPool.allowCoreThreadTimeOut(true);
instance.setChnlBackendQueryPool(chnlBackendQueryPool);
}
}
}
return instance;
} public ThreadPoolExecutor getChnlBackendQueryPool() {
return chnlBackendQueryPool;
} public static void setChnlBackendQueryPool(ThreadPoolExecutor chnlBackendQueryPool) {
CustomAsyncScheduler.chnlBackendQueryPool = chnlBackendQueryPool;
} public static void setInstance(CustomAsyncScheduler instance) {
CustomAsyncScheduler.instance = instance;
} }
2、创建线程任务
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; /**
* @Description: 创建线程任务服务
* @ClassName: CustomMultiThreadingService
* @Author: OnlyMate
* @Date: 2018年9月21日 下午3:17:57
*/
@Service
public class CustomMultiThreadingService {
private Logger logger = LoggerFactory.getLogger(CustomMultiThreadingService.class);
/**
* @Description:通过@Async注解表明该方法是一个异步方法,
* 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
* @Title: executeAysncTask1
* @Date: 2018年9月21日 下午2:54:32
* @Author: OnlyMate
* @Throws
* @param i
*/
@Async
public void executeAysncTask1(Integer i){
logger.info("CustomMultiThreadingService ==> executeAysncTask1 method: 执行异步任务{} ", i);
} /**
* @Description:通过@Async注解表明该方法是一个异步方法,
* 如果注解在类级别上,则表明该类所有的方法都是异步方法,而这里的方法自动被注入使用ThreadPoolTaskExecutor作为TaskExecutor
* @Title: executeAsyncTask2
* @Date: 2018年9月21日 下午2:55:04
* @Author: OnlyMate
* @Throws
* @param i
*/
@Async
public void executeAsyncTask2(Integer i){
logger.info("CustomMultiThreadingService ==> executeAsyncTask2 method: 执行异步任务{} ", i);
} /**
* @Description: 异步线程调度管理器创建线程任务
* @Title: executeAsyncTask3
* @Date: 2018年9月21日 下午3:32:28
* @Author: OnlyMate
* @Throws
* @param i
*/
public void executeAsyncTask3(Integer i){
CustomAsyncScheduler.getInstance().getChnlBackendQueryPool().execute(new Runnable() {
@Override
public void run() {
logger.info("CustomMultiThreadingService ==> executeAsyncTask3 method: 执行异步任务{} ", i);
}
}); }
}
3、触发线程任务
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.only.mate.springboot.multithreading.CustomMultiThreadingService; /**
* @Description:自定义多线程Controller
* @ClassName: CustomMultiThreadingController
* @Author: OnlyMate
* @Date: 2018年9月21日 下午3:02:49
*/
@Controller
@RequestMapping(value="/multithreading")
public class CustomMultiThreadingController {
@Autowired
private CustomMultiThreadingService customMultiThreadingService; @ResponseBody
@RequestMapping(value="/dotask")
public String doTask() {
for (int i=0;i<10;i++){
customMultiThreadingService.executeAysncTask1(i);
customMultiThreadingService.executeAsyncTask2(i);
} return "success";
} @ResponseBody
@RequestMapping(value="/dojob")
public String doJob() {
for (int i=0;i<10;i++){
customMultiThreadingService.executeAysncTask1(i);
customMultiThreadingService.executeAsyncTask2(i);
customMultiThreadingService.executeAsyncTask3(i);
}
return "success";
}
}
4、效果图
访问http://localhost:8088/springboot/multithreading/dojob

Spring Boot实践——多线程的更多相关文章
- Spring Boot实践——Spring AOP实现之动态代理
Spring AOP 介绍 AOP的介绍可以查看 Spring Boot实践——AOP实现 与AspectJ的静态代理不同,Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改 ...
- Spring Boot实践——AOP实现
借鉴:http://www.cnblogs.com/xrq730/p/4919025.html https://blog.csdn.net/zhaokejin521/article/detai ...
- Spring Boot 实践 :Spring Boot + MyBatis
Spring Boot 实践系列,Spring Boot + MyBatis . 目的 将 MyBatis 与 Spring Boot 应用程序一起使用来访问数据库. 本次使用的Library spr ...
- spring boot 实践
二.实践 一些说明: 项目IDE采用Intellij(主要原因在于Intellij颜值完爆Eclipse,谁叫这是一个看脸的时代) 工程依赖管理采用个人比较熟悉的Maven(事实上SpringBoot ...
- spring boot 实践总结(转)
pring Boot是最流行的用于开发微服务的Java框架.在本文主要分享的是在专业开发中使用Spring Boot所采用的最佳实践.这些内容是基于个人经验和一些熟知的Spring Boot专家的文章 ...
- Spring Boot 定时+多线程执行
Spring Boot 定时任务有多种实现方式,我在一个微型项目中通过注解方式执行定时任务. 具体执行的任务,通过多线程方式执行,单线程执行需要1小时的任务,多线程下5分钟就完成了. 执行效率提升10 ...
- Spring Boot实践——用外部配置填充Bean属性的几种方法
引用:https://blog.csdn.net/qq_17586821/article/details/79802320 spring boot允许我们把配置信息外部化.由此,我们就可以在不同的环境 ...
- Spring Boot实践——事件监听
借鉴:https://blog.csdn.net/Harry_ZH_Wang/article/details/79691994 https://blog.csdn.net/ignorewho/arti ...
- Spring Boot实践——基础和常用配置
借鉴:https://blog.csdn.net/j903829182/article/details/74906948 一.Spring Boot 启动注解说明 @SpringBootApplica ...
随机推荐
- 局域网内web地图的简单实现
首先,我先说一下这次的主要目的.我们的想法是在不连互联网的局域网中搭起来一个地图服务,类似于百度地图的网页版本,功能最少要有看地图.放缩.标记.批量标记.实时经纬度坐标.这个东西还是让我费了一番力气( ...
- 数论练习(5)——青蛙的约会(扩gcd)
青蛙的约会 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 122502 Accepted: 26015 Descript ...
- Java——抽象类、接口
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- Winform开发常用控件之DataGridView的简单数据绑定——自动绑定
DataGridView控件可谓是Winform开发的重点控件,对于数据的呈现和操作非常方便,DataGridView可谓是既简单又复杂.简单在于其已经集成了很多方法,复杂在于可以使用其实现复杂的数据 ...
- 关于SSL的error问题
今天模拟网页版微信登录的时候又碰到一个SSLError的问题 requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SS ...
- Mac: iTerm2使用
From: http://www.cnblogs.com/noTice520/p/3190529.html 之前一直有朋友要我分享下在用的mac软件,今天有空就来写一下,可能不止于软件,会有一些配置或 ...
- cratedb geo 查询
cratedb支持的geo 查询还相对比较全,开发基本的功能已经够用了 安装cratedb 使用docker docker run -d -p 4200:4200 crate 创建数据库 创建表 CR ...
- 【转】嵌入式Linux启动配置文件及脚本
原文网址:http://blog.csdn.net/shuaishuai80/article/details/6202497 使用Busybox制作根文件系统时,/etc目录非常重要,它包含了嵌入式L ...
- xmlns和xsi之schemaLocation
appplicationContex.xml文件报错:元素 "util:constant" 的前缀 "util" 未绑定 在根节点添加了“xmlns:util= ...
- 解决移动端H5海报滑动插件适应大部分手机问题 手机端高度自适应
Html5微信端滑屏海报在各种尺寸的手机上总会有这样那样的问题,经过多次制作总结出来一些小心得,分享下. 我使用的是jquery插件swiper.min.js,动画可以利用animate.css,如果 ...