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 ...
随机推荐
- [转载]java调用本地dos命令
在社区看到java调用本地dos命令的代码,特贴出来 String command = "ipconfig"; Runtime run = Runtime.getRuntime() ...
- linux提权辅助工具(三):privchecker.py
来自:https://www.securitysift.com/download/linuxprivchecker.py #!/usr/env python ##################### ...
- mcc,mex,mbuild
mcc将M文件转换成C/C++文件和相应的MEX包裹文件(需要Matlab编辑器),但在特定条件下可以自动调用mbuild或者mexmex将C/C++文件(入口函数为mexfunction())编译成 ...
- 管道通信Pipe
通信原理: 在内存中开辟管道空间,生成管道操作对象,多个进程使用“同一个”管道对象进程操作即可实现通信 函数方法: fd1,fd2 = Pipe(duplex = True) 功能: 创建管道 参数: ...
- ubuntu修改分辨率
ubuntu分辨率真是坑爹,不知什么原因,ubuntu分辨率一下子变了,通过,显示->分辨率,都改不过来... 无奈,有重装系统的冲动,从网上找了很多方法,都不管用,有一次,在这里 sudo g ...
- 如何在Oracle官网下载java的JDK最新版本和历史版本
官网上最显眼位置只显示了Java SE的JDK的最新版本下载链接,因为都是英文,如果英文不是很好,寻找之前的JDK版本需要很长时间,而且未必能在那个隐蔽的位置找到之前版本列表. 今天小编来给你详细讲解 ...
- JS 实战2(邮箱选人功能)
点击选人打开新的窗口,新窗口中选取之后点击确定将所选内容传给原窗口,并关闭当前窗口 <%@ Page Language="C#" AutoEventWireup=" ...
- 为什么要使用索引?-Innodb与Myisam引擎的区别与应用场景
Innodb与Myisam引擎的区别与应用场景 http://www.cnblogs.com/changna1314/p/6878900.html https://www.cnblogs.com/ho ...
- 《DSP using MATLAB》Problem 2.8
1.代码: 从MATLAB官方网上下载的. %*************************************************************************% %A ...
- 使用bit管理npm包
npm 包给共享,团队写作有好多问题需要解决,类似的解决方案有lerna yarn 使用monorepo,bit 官方有相关的比较 以下只说明如何进行简单的项目使用 网站 https://bitsrc ...