本文通过代码来演示如果在spring boot的项目中使用多线程,也就是异步。要异步并不难,我们写的代码天天都在跟异步多线程打交道,容易让人感到迷惑的是异步的底层原理,不仅要会使用,更要熟悉其实现原理,才能更加灵活地在项目中进行运用。

首先在pom.xml中引入依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zhangxueliang.demo</groupId><artifactId>springbootdemo</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>springbootdemo</name><description>Demo project for Spring Boot</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.0.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>fluent-hc</artifactId><version>4.5.3</version></dependency><dependency><!-- jsoup HTML parser library @ https://jsoup.org/ --><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.10.3</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.31</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.12</version><scope>runtime</scope></dependency><!--集成mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!--整合freemarker--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!--整合thymleaf--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--整合alibaba easyPOI--><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>3.2.0</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifactId><version>3.2.0</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>3.2.0</version></dependency><!-- lombok可使代码更简洁 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><!--热部署--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><!--引入AOP依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!--整合MongoDB--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency><!--整合rabbitmq--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId></dependency><!--使用@Slf4j注解--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--爬虫相关依赖--><!-- jsoup HTML parser library @ https://jsoup.org/ --><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.11.2</version></dependency><!--整合POI--><!--<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>RELEASE</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>RELEASE</version></dependency>--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.15</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>3.15</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.15</version></dependency><!-- webMagic start --><dependency><groupId>us.codecraft</groupId><artifactId>webmagic-core</artifactId><version>0.7.3</version></dependency><dependency><groupId>us.codecraft</groupId><artifactId>webmagic-extension</artifactId><version>0.7.3</version></dependency><dependency><groupId>us.codecraft</groupId><artifactId>webmagic-extension</artifactId><version>0.7.3</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency><!-- webMagic end --><!--引入log工程jar--><!--<dependency><groupId>com.fengyuncx.log</groupId><artifactId>fy-log</artifactId><version>0.0.1-SNAPSHOT</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/fy-log-0.0.1-SNAPSHOT.jar</systemPath></dependency>--></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><!--打包时将引入的本地jar打进去--><configuration><includeSystemScope>true</includeSystemScope></configuration></plugin></plugins></build></project>

在启动类上添加@EnableAsync注解,开启异步.注意:如果在配置类上添加了该注解,启动类上就无需添加。

@SpringBootApplication
//@EnableAsync//开启异步
public class ZxlDemoApplication {public static void main(String[] args) {SpringApplication.run(ZxlDemoApplication.class, args);}}

编写多线程配置类

/*** 线程配置类*/
@Configuration
@EnableAsync
public class AsyncTaskConfig implements AsyncConfigurer {// ThredPoolTaskExcutor的处理流程// 当池子大小小于corePoolSize,就新建线程,并处理请求// 当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去workQueue中取任务并处理// 当workQueue放不下任务时,就新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理// 当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();taskExecutor.setCorePoolSize(50);// 核心线程数taskExecutor.setMaxPoolSize(50);// 最大线程数taskExecutor.setQueueCapacity(200);// 等待队列taskExecutor.setThreadNamePrefix("zxl_taskExecutor-");//线程名称前缀taskExecutor.initialize();return taskExecutor;}@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return null;}
}

编写线程任务执行类

package com.zhangxueliang.demo.springbootdemo.async;import java.util.Random;
import java.util.concurrent.Future;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;/*** 线程执行任务类*/
@Service
public class AsyncTaskService {private Logger logger = LoggerFactory.getLogger(AsyncTaskService.class);Random random = new Random();// 默认构造方法@Async// 表明是异步方法// 无返回值public void executeAsyncTask(String msg) {System.out.println(Thread.currentThread().getName()+"开启新线程执行" + msg);}@Asyncpublic Future<String> doReturn(int i){logger.info(">>>>>>>>>>>>>>线程名>>>>>>>>>>>>>>"+Thread.currentThread().getName());try {// 这个方法需要调用500毫秒Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}// 消息汇总return new AsyncResult<>(String.format("这个是第{%s}个异步调用的证书", i));}/*** 异常调用返回Future* @return* @throws InterruptedException*/@Asyncpublic Future<Long> asyncInvokeReturnFuture() throws InterruptedException {long start = System.currentTimeMillis();Thread.sleep(5000);Future<Long> future = new AsyncResult<Long>((System.currentTimeMillis()-start));// Future接收返回值,这里是String类型,可以指明其他类型return future;}@Asyncpublic Future<Long> asyncInvokeReturnFuture2() throws InterruptedException {long start = System.currentTimeMillis();Thread.sleep(3500);Future<Long> future = new AsyncResult<Long>((System.currentTimeMillis()-start));// Future接收返回值,这里是String类型,可以指明其他类型return future;}@Asyncpublic Future<Long> asyncInvokeReturnFuture3() throws InterruptedException {long start = System.currentTimeMillis();Thread.sleep(2500);Future<Long> future = new AsyncResult<Long>((System.currentTimeMillis()-start));// Future接收返回值,这里是String类型,可以指明其他类型return future;}
}

编写测试类,也就是调用多线程任务。

@RunWith(SpringRunner.class)
@SpringBootTest
public class ZxlTest {private Logger logger = LoggerFactory.getLogger(ZxlTest.class);@Autowiredprivate AsyncTaskService asyncTaskService;@Testpublic void testAsync(){
//        String msg="测试测试";
//        System.out.println(Thread.currentThread().getName()+":"+msg);
//        asyncTaskService.executeAsyncTask(msg);try {long start = System.currentTimeMillis();Future<Long> future = asyncTaskService.asyncInvokeReturnFuture();Future<Long> future2 = asyncTaskService.asyncInvokeReturnFuture2();Future<Long> future3 = asyncTaskService.asyncInvokeReturnFuture3();Long l1 = future.get();//5000Long l2 = future2.get();//3500Long l3 = future3.get();//2500System.out.println(Thread.currentThread().getName()+"*************************************");System.out.println(Thread.currentThread().getName()+(l1+l2+l3 ));System.out.println(Thread.currentThread().getName()+"-------------------------------------");System.out.println(Thread.currentThread().getName()+(System.currentTimeMillis()-start));System.out.println(Thread.currentThread().getName()+"+++++++++++++++++++++++++++++++++++++");} catch (Exception e) {e.printStackTrace();}}
}

Spring Boot项目开启异步使用多线程完整代码案例相关推荐

  1. Spring Boot 整合 Mybatis Annotation 注解的完整 Web 案例

    摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 公司需要人.产品.业务和方向,方向又要人.产品.业务和方向,方向- 循环』 本文提纲 一 ...

  2. 从服务器基础环境配置到搭建Docker+Gitlab+Gitlab Runner,完整介绍Spring Boot项目的持续集成与持续交付具体实现!

    1. 序言 在大学的课程学习,非常注重团队协作的培养,在企业开发中,团队协作开发项目的场景更是甚多.另外,在当下的热门技术栈中,微服务开发模式.前后端分离开发模式逐渐盛行,Spring Boot.VU ...

  3. java5分钟项目讲解_5分钟快速创建spring boot项目的完整步骤

    前言 上一篇博客说了如何创建spring boot项目,但是有些同学会觉得有点麻烦,有没有什么快速学会能快速创建spring boot项目的方法,答案是肯定的.接下来我们就一起来快速创建一个sprin ...

  4. 如何使用Spring初始化程序创建Spring Boot项目

    你好朋友, 如果您以前使用过Spring框架,则必须意识到,即使要开始使用基本的Spring功能也需要付出一些真正的努力.有了Spring Boot,最初的麻烦就消失了,您可以在数分钟内开始使用. 欢 ...

  5. 《SpringCloud超级入门》Spring Boot项目搭建步骤(超详细)《六》

    目录 编写第一个 REST 接口 读取配置文件 profiles 多环境配置 热部署 actuator 监控 自定义 actuator 端点 统一异常处理 异步执行 随机端口 编译打包 在 Sprin ...

  6. Vue + Spring Boot 项目实战(十五):动态加载后台菜单

    重要链接: 「系列文章目录」 「项目源码(GitHub)」 本篇目录 前言 一.后端实现 1.表设计 2.pojo 3.菜单查询接口(树结构查询) 二.前端实现 1.后台页面设计 2.数据处理 3.添 ...

  7. 【MySQL】Spring Boot项目基于Sharding-JDBC和MySQL主从复制实现读写分离(8千字详细教程)

    目录 前言 一. 介绍 二. 主从复制 1. 原理 2. 克隆从机 3. 克隆从机大坑 4. 远程登陆 5. 主机配置 6. 从机配置 7. 主机:建立账户并授权 8. 从机:配置需要复制的主机 9. ...

  8. Spring Boot 项目搭建

    从根本上来说,Spring Boot的项目只是普通的Spring项目,只是它们正好用到了Spring Boot的起步依赖和自动配置而已.因此,那些你早已熟悉的从头创建Spring项目的技术或工具,都能 ...

  9. spring boot项目 中止运行 最常用的几种方法

    spring boot项目 中止运行 最常用的几种方法: 1. 调用接口,停止应用上下文 @RestController public class ShutdownController impleme ...

最新文章

  1. 使用sed和awk取除最后两个字段之外的字段
  2. 九度OJ 1336:液晶屏裁剪 (GCD)
  3. 汇编语言--单步中断
  4. nas php.ini,php.ini 配置文件常用详解
  5. linux 内核移植和根文件系统的制作【转载】
  6. 【BZOJ2131】免费的馅饼,坐标转换与DP
  7. python初级爬虫工程师_如何入行爬虫工程师
  8. 一文了解全面静态代码分析
  9. 宝峰对讲机16频率表_宝峰对讲机频率设置 设置对讲机频率的技巧
  10. ASTC压缩格式总结
  11. 医学案例统计分析与SAS应用--自学笔记
  12. 1133_SICP开发环境搭建
  13. Cascade EF-GAN: 局部聚焦渐进式面部表情编辑
  14. 【面试】前端面试之开发性能篇
  15. 数智化未来5大趋势——CDEC2020中国数字智能生态大会上海站生态伙伴发展状况调查...
  16. 使用浏览器转化ASCII码为字符
  17. android获取存储设备根目录,浅谈android获取存储目录(路径)的几种方式和注意事项...
  18. 双节连壁,iMindMap钜惠来袭
  19. 学ajax要学php吗,javascript – Ajax新手学习(PHP JQuery)
  20. ubuntu12.10安装NCL问题

热门文章

  1. 【Python基础】Python中必须知道的5对魔术方法
  2. 【CV】图像分割2020,架构,损失函数,数据集,框架的整理和总结
  3. AI基础:正则表达式
  4. 优化 | 利用SciPy求解非线性规划问题
  5. 机器学习入门开源资料
  6. 网易云信携手SNH48 GROUP,打造在线追星新体验
  7. Rancher 2.0 里程碑版本:支持添加自定义节点!
  8. https和server-status配置案例
  9. 《Spring 3.0就这么简单》——1.6 展现层
  10. swift3.0截取View生成图片 图片截取成新图片