【spring boot】13.在spring boot下使用多线程
使用场景:
方法处理到某一步,需要将信息交给另一个线程去处理!!
===================================================================================
第一种:最简单的Runnable
public void test(String msg){
System.out.println(Thread.currentThread().getName()+":"+msg);
Runnable runnable = dealMsg(msg);
//将返回的runnable对象传入,并start()启动线程
new Thread(runnable).start();
}
//创建一个Runnable,重写run方法
public Runnable dealMsg(String msg){
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("新开线程中处理:"+msg);
}
}; return runnable;
}
====================================================================================================
第二种:自己创建JDK线程池,交给spring管理,然后将任务交给线程池即可
1.创建线程池,交给spring管理
package com.sxd.util; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; @Configuration
public class ThreadConfig { /**
*newFixedThreadPool
创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。 newCachedThreadPool
创建一个可缓存的线程池。这种类型的线程池特点是:
1).工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。
2).如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。 newSingleThreadExecutor
创建一个单线程化的Executor,即只创建唯一的工作者线程来执行任务,如果这个线程异常结束,会有另一个取代它,保证顺序执行(我觉得这点是它的特色)。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的 。 newScheduleThreadPool
创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer。
* @return
*/
@Bean
public ExecutorService getExecutorTools(){
ExecutorService executorService = Executors.newFixedThreadPool(8);
return executorService;
} }
2.使用它
import org.springframework.stereotype.Component; import javax.annotation.Resource;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future; @Component
public class Consumer1 { @Resource
private ExecutorService executorService; public void test(String msg){
System.out.println(Thread.currentThread().getName()+":"+msg); /**
* 分类1:可以返回值的 Callable
*/
Future fal = executorService.submit(new Callable<String>() {
@Override
public String call() {
System.out.println(Thread.currentThread().getName()+":"+msg);
return "处理成功!";
}
}); try {
System.out.println(fal.get());
}catch (Exception e){
System.out.println(e);
} /**
* 分类2:不会返回值的 Runnable
*/
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+msg);
}
}); /**
* 分类3:也可以这样
*/
executorService.submit(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":"+msg);
}
}); } }
====================================================================================================
第三种:使用spring封装的线程池
1.创建线程配置类【
@ComponentScan("com.sxd") 标明会在哪个包下使用多线程
】
package com.sxd.util; 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; @Configuration
@ComponentScan("com.sxd")
@EnableAsync
// 线程配置类
public class AsyncTaskConfig implements AsyncConfigurer { // ThredPoolTaskExcutor的处理流程
// 当池子大小小于corePoolSize,就新建线程,并处理请求
// 当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去workQueue中取任务并处理
// 当workQueue放不下任务时,就新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理
// 当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁 @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 null;
}
}
2.创建线程任务执行类
package com.sxd.util; import java.util.Random;
import java.util.concurrent.Future; import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service; @Service
// 线程执行任务类
public class AsyncTaskService { Random random = new Random();// 默认构造方法 @Async
// 表明是异步方法
// 无返回值
public void executeAsyncTask(String msg) {
System.out.println(Thread.currentThread().getName()+"开启新线程执行" + msg);
} /**
* 异常调用返回Future
*
* @param i
* @return
* @throws InterruptedException
*/
@Async
public Future<String> asyncInvokeReturnFuture(int i) throws InterruptedException {
System.out.println("input is " + i);
Thread.sleep(1000 * random.nextInt(i)); Future<String> future = new AsyncResult<String>("success:" + i);// Future接收返回值,这里是String类型,可以指明其他类型 return future;
}
}
3.使用它
@Component
public class Consumer1 { @Resource
private AsyncTaskService asyncTaskService; public void test(String msg){
System.out.println(Thread.currentThread().getName()+":"+msg); asyncTaskService.executeAsyncTask(msg); } }
====================================================================================================
第四种:在代码中启动异步处理最简单的代码
public void test(){
new Thread(()->doReplace(replaceLog)).start();
} public void doReplace(String replaceLog){ //异步处理的业务
}
======================================
就这么多,再补充噻!!
【spring boot】13.在spring boot下使用多线程的更多相关文章
- Spring第13篇—–Spring整合Hibernate之声明式事务管理
不容置疑的我们可以知道Spring的事务管理是通过AOP(AOP把我们的事务管理织入到我们的业务逻辑里面了)的方式来实现的,因为事务方面的代码与spring的绑定并以一种样板式结构使用.(面向切面编程 ...
- Spring Boot Document Part II(下)
Part II. Getting started 11. 开发第一个Spirng Boot Application使用Spring Boot的关键特征开发一个基于JAVA Web的“Hello Wor ...
- 开源的13个Spring Boot 优秀学习项目!超53K星,一网打尽!
Spring Boot 算是目前 Java 领域最火的技术栈了,也是Java开发人员不得不掌握的技术,今天给大家整理了13个优质 Spring Boot 开源项目给大家参考,希望能够帮助到正在学习 S ...
- 【spring boot】在spring boot下使用多线程
使用场景: 方法处理到某一步,需要将信息交给另一个线程去处理!! =================================================================== ...
- spring boot profiles 实现多环境下配置切换 docker版
1,前言 开发环境总需要调试,docker直接部署不需要调试,环境配置不一样,这里的目的只是,在docker文件环境与开发环境使用不同的配置文件,项目结构如下 2,设置项目配置文件 默认配置文件 ap ...
- Spring Boot (13) druid监控
druid druid是和tomcat jdbc一样优秀的连接池,出自阿里巴巴.除了连接池,druid哈hi有一个很实用的监控功能. pom.xml 添加了以下依赖后,会自动用druid连接池替代默认 ...
- 使用 Spring Boot 快速构建 Spring 框架应用--转
原文地址:https://www.ibm.com/developerworks/cn/java/j-lo-spring-boot/ Spring 框架对于很多 Java 开发人员来说都不陌生.自从 2 ...
- 使用 Spring Boot 快速构建 Spring 框架应用,PropertyPlaceholderConfigurer
Spring 框架对于很多 Java 开发人员来说都不陌生.自从 2002 年发布以来,Spring 框架已经成为企业应用开发领域非常流行的基础框架.有大量的企业应用基于 Spring 框架来开发.S ...
- spring cloud: 升级到spring boot 2.x/Finchley.RELEASE遇到的坑
spring boot2.x已经出来好一阵了,而且spring cloud 的最新Release版本Finchley.RELEASE,默认集成的就是spring boot 2.x,这几天将一个旧项目尝 ...
随机推荐
- HDU 3376 费用流 Matrix Again
题意: 给出一个n × n的矩阵,每个格子中有一个数字代表权值,找出从左上角出发到右下角的两条不相交的路径(起点和终点除外),使得两条路径权值之和最大. 分析: 如果n比较小的话是可以DP的,但是现在 ...
- python基础补漏-07-正则表达式
字符: . 匹配除了换行符以外的任意字符 \w 匹配字母或者数字或下划线或汉字(除了特殊字符外都能匹配) \s 匹配任意空白符 \d 匹配数字 \b 匹配单词的开始或者结束 ^ 匹配字符串 ...
- HTTP LVS
1. Configure the director 2.
- [笔记]Docker解决了什么问题?
Docker的优势: 环境依赖问题 更轻量的虚拟化,节省了虚拟机的性能损耗 Docker应用场景: 程序分发,gitlab的安装很恶心吧,所以有人做了gitlab的image 部署发布,这点对运维的同 ...
- 解决vue、cnpm造成的样式错位问题
删除node_modules文件夹使用npm install不要使用cnpm install
- 九度oj 题目1465:最简真分数
题目描述: 给出n个正整数,任取两个数分别作为分子和分母组成最简真分数,编程求共有几个这样的组合. 输入: 输入有多组,每组包含n(n<=600)和n个不同的整数,整数大于1且小于等于1000. ...
- 【转】学习设计模式之前你必须掌握的-看懂UML类图
UML类图是UML(unified modeling language,标准建模语言)五种图示法中静态图的一种-用来描述系统中类的静态结构,不仅定义系统中的类,表示类之间的联系如关联.依赖.聚合等,也 ...
- RHEL 7.3修改网卡命名规则为ethX
RHEL 7网卡默认命名规则:以太网卡(Ethernet)为enX,无线网卡(WLAN)为wlX,修改网卡命名规则为ethX如下: 1.修改/etc/sysconfig/grub文件,添加net.if ...
- 【Luogu】P3979遥远的国度(树链剖分)
题目链接 不会换根从暑假开始就困扰我了……拖到现在…… 会了还是很激动的. 换根操作事实上不需要(也不能)改树剖本来的dfs序……只是在query上动动手脚…… 设全树的集合为G,以root为根,u在 ...
- 【Luogu】P1903数颜色(带修改莫队)
题目链接 带修改莫队模板. 加一个变量记录现在是第几次修改,看看当前枚举的询问是第几次修改,改少了就改过去,改多了就改回来. 话说我栈用成队列了能过样例?!!!! 从此深信一句话:样例是出题人精心设计 ...