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 ...
随机推荐
- Object.assign()是浅拷贝
浅拷贝: 复制的值指向同一个内存地址 深拷贝:复制的值指向新的内存地址 var a = { xm: { name: 'xiaoming' } } var b = Object.assign({}, a ...
- VAE--就是AutoEncoder的编码输出服从正态分布
花式解释AutoEncoder与VAE 什么是自动编码器 自动编码器(AutoEncoder)最开始作为一种数据的压缩方法,其特点有: 1)跟数据相关程度很高,这意味着自动编码器只能压缩与训练数据相似 ...
- asp.net验证码图片生成示例
验证码,一个很常见的东西.不管你是使用者还是开发者,这个东西80%的人都见到过,但是之前有人给我说过这么一句话“内行看门道,外行看热闹!”,仔细琢磨一下还真的是那么一回事.对于怎么实现验证码,闲话不多 ...
- mysql 简单级联的学习
数据库上面一直是我的弱项,昨天突然想到,简单的级联,即一个表中的列表删除了,另外一个依赖这个表的其他数据应该也会删除,当时想了下,可以根据外键来判断把其他表的数据给删除了,但是这样一来好像要必须知道其 ...
- 宏使用 Tricks
人为地定义一些"无意义"的宏(宏名本身有意义),以起到提升代码程序的可读性. 1. IN/OUT 指定参数用于输入还是输出: #define IN #define OUT void ...
- .NET CORE微服务实践
.NET CORE微服务实践 https://www.cnblogs.com/zengqinglei/p/9570343.html .NET CORE 实践部署架构图 实践源码:https://git ...
- fff
https://qa.tutormeet.com/tutormeet/tutormeet_FF.html?lang=3&data=MjAxODAzMjcxODAwMTQ1OXwyNzQ2fGp ...
- 使用IAR编译STM8S 怎样生产烧录文件
IAR编译后能够生成的烧录文件格式有4中,例如以下 第一种是Motorola,其生成文件和STVD生成烧录文件.s19格式一样的,即能够通用 另外一种是16进制,keil等等常都用到的. 第三种是 ...
- LoadRunner安装+破解+汉化
安装 一.需要准备的东东: 1.电脑的操作系统:Win7旗舰版(不解释,这个版本安装问题最少了) 2.LoadRunner11+破解文件+汉化文件+删除注册表工具 3.强大的搜索引擎 二.安装过程 用 ...
- linux之 LVM扩容
1. 查看本机现在磁盘的情况[root@oralce10g ~]# df Filesystem 1K-blocks Used Available Use% Mounted on/dev/mapper/ ...