基于SpringBoot+Async注解整合多线程

2023-11-09

提示:本文没有使用原生的创建线程方式,默认已掌握创建线程的四种方式
全文基于SpringBoot框架,要求读者掌握SpringBoot操作
本人能力有限,如有遗漏或错误,敬请指正,谢谢


其他文章

1.Java多线程基本概念和常用API(面试高频)
2.线程安全问题(synchronized解决,各种类型全)
3.Java并发线程池使用和原理(通俗易懂版)
4.基于SpringBoot+Async注解整合多线程

前言

学习一门技术最好使用wwh方法
what:这门技术是什么
why:为什么用这个技术,使用会有什么优化
how:怎么使用


提示:以下是本篇文章正文内容,下面案例可供参考

一、为什么要使用多线程?

先谈谈单线程的使用:
在普通业务下,要查询多个表,调用多个接口(比如根据id查询A表,B表,C表),同步进行,要等待每个接口执行后才走下一个接口,耗时久
单线程接口执行过程
为了提高效率,使用多线程异步的方式:
多线程接口执行过程

二、业务中使用多线程方式

1.传统方式

代码如下(示例):手动开启多线程,如果业务都需要,那么每个都要自己编码

public static void main(String[] args) {
    System.out.println("主线程开启");
    //创建线程池
    ThreadPoolExecutor executor=new ThreadPoolExecutor(5,5,10, TimeUnit.SECONDS,new LinkedBlockingDeque<>());
    executor.execute(()->{
        try {
            Thread.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"多线程执行");
    });
    System.out.println("主线程结束");
}

2.使用Async注解

  • 配置类加上@EnableAsync() :开启异步执行
  • 在调用的方法上加上@Async:
    可以让某个方法变成异步调用的时候,不是以主线程调用,而是取线程池里的线程调用,多线程执行
  • @Async(“指定线程池名”) 不指定用默认线程池

@Async生效条件:
1.方法是public的
2.在同一个类中调用无效,因为它绕过代理并直接调用底层方法。如A和B方法在一个类中,在B方法上加@Async注解,A调用B是不会使用多线程的

代码如下(示例):
在多线程方法中睡眠3s更方便体现异步执行

@RequestMapping("/test")
public void test(){
    System.out.println("主线程"+Thread.currentThread().getName()+"开启");
    threadTask.test();
    System.out.println("主线程结束");
}

@Async()
void test() {
    System.out.println(Thread.currentThread().getName()+"被调用了");
    try {
        Thread.sleep(3);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+"结束了");
}
输出:
主线程 xxx 开启
主线程结束
异步线程名 被调用
异步线程名 结束了

3.源码分析:@Async使用的默认线程池

默认使用Spring创建ThreadPoolTaskExecutor。

默认核心线程数:8,最大线程数:Integet.MAX_VALUE
队列使用LinkedBlockingQueue,容量是:Integet.MAX_VALUE
空闲线程保留时间:60s
线程池拒绝策略:AbortPolicy

源码分析:
线程名以task-开头
在这里插入图片描述
默认线程池配置
在这里插入图片描述

4.不使用默认线程池,自定义线程池

ThreadPoolTaskExecutor是spring core包中的,而ThreadPoolExecutor是JDK中的JUC。ThreadPoolTaskExecutor是对ThreadPoolExecutor进行了封装处理。
Spring项目用ThreadPoolTaskExecutor更方便

@Configuration
@EnableAsync //启用异步任务,开启多线程    配合@Async注解在方法上,表示这个方法被调用时,会从线程池拿出线程来调用
public class ThreadConfig {
    @Bean
    public ThreadPoolTaskExecutor executor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
      	//配置核心线程数
        executor.setCorePoolSize(15);
      	//配置最大线程数
        executor.setMaxPoolSize(30);
      	//配置队列大小
        executor.setQueueCapacity(1000);
      	//线程的名称前缀
        executor.setThreadNamePrefix("Executor-");
      	//线程活跃时间(秒)
        //executor.setKeepAliveSeconds(60);
      	//等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
      	//设置拒绝策略
        //executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
      	//执行初始化
        executor.initialize();
        return executor;
    }
}

5.案例:批量插入数据

插入100w数据,分10次插入,采用多线程方式
持久层使用mybatis-plus
使用JUC线程类

@RestController
public class TestController {
    @Autowired
    private ThreadPoolTaskExecutor executor;
    @Autowired
    private UserService userService;

   @RequestMapping("/test1")
    public void test1(){
    	//10表示线程有10个 
       CountDownLatch cdl = new CountDownLatch(10); 
       Long start=System.currentTimeMillis();
       for(int i=1;i<=10;i++){
           executor.execute(() -> {
               System.out.println("开启线程:"+Thread.currentThread().getName());
               List<User> list=new ArrayList<>();
               for(int j=1;j<=100000;j++){
                   list.add(new User(UUID.randomUUID().toString(),"aaa"));
               }
               userService.saveBatch(list,10000);
               //每执行完一个线程,就减一
               cdl.countDown(); 
           });

       }
       try {
       //如果线程数不为0,就一直等待,不用这个判断算不出 本次插入时间
           cdl.await(); 
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       Long end=System.currentTimeMillis();
       System.out.println(end-start);
    }
}

总结

使用步骤:
1.不想用Spring配置的线程池,则自己创建Bean
2.开启@EnableAsync异步
3.在调用的方法加上@Async注解

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于SpringBoot+Async注解整合多线程 的相关文章

  • 在 Java 中使用 Apache POI XWPF 在同一个 Word 文档中横向和纵向页面

    我正在尝试使用 Java 和 Apache POI 库创建一个包含一些横向页面和一些纵向页面的 Word 文档 我可以更改所有页面的方向 但有没有办法只更改其中某些页面的方向 我尝试过使用不同的部分和主体 但无济于事 目前我已经编写了一个函
  • 在 Java 和 C 中在运行时调用名为“string”的方法

    我们如何调用名称为的方法string在运行时 谁能告诉我如何在 Java 和 C 中做到这一点 在java中可以通过反射api来完成 看一下Class getMethod String methodName Class parameterT
  • 如何使用 Apache Camel 路由从授权服务器获取访问令牌?

    我有一个授权服务器 带有注释的简单类 SpringBootApplication RestController Configuration EnableAuthorizationServer oauth2 security 在端口上运行80
  • Spring 可以理解 @Inject 替换 Weld 作为 JSR-299 实现吗?

    我从几个网页中注意到 Spring 3 0 显然支持来自 JSR 330 的 Inject 由于我们确实希望在 Web 应用程序和独立应用程序的库中使用 JSR 299 语法进行依赖项注入 并且有 Weld 的替代方案 因此如果 Sprin
  • 将图像缩略图上传到服务器,而不上传整个图像

    据我所知 我在这里问的是不可能的 但我想无论如何我都会问 以防我遗漏了什么 假设您想让用户上传 JPG 图像 并且这些图像被缩放为较小的图标 并且原始图像始终被丢弃并且不再需要 有没有什么方法可以在大多数现代浏览器中普遍使用 让用户选择硬盘
  • 全屏独占模式下的 AWT 框架在窗口弹出对话框中最小化

    我正在开发一个在全屏独占模式下使用 awt 框架的应用程序 一切正常 直到弹出窗口可见 这会抢走焦点 我的应用程序将被最小化 这是我的框架的初始化代码 if ApplicationConfig getInstance useFullscre
  • 指定自定义应用程序上下文

    我们正在将一些数据服务从使用 jersey spring 的 Jersey 1 x 迁移到使用 jersey spring3 的 Jersey 2 x 我们有一些继承自 JerseyTest 的测试类 其中一些类使用 web xml 文件中
  • Maven:缺少工件 org.springframework:spring:jar:4.2.6

    我在 SpringToolSuite 中有一个动态 Web 项目 它被转换为 Maven 项目 我遇到问题 缺少工件 org springframework spring jar 4 2 6 我已经尝试清理 重建和运行该项目 它给 读取文件
  • 内容安全策略:页面设置阻止自行加载资源?

    我有基于 Java 的 Web 应用程序运行在Tomcat http en wikipedia org wiki Apache Tomcat6 我的应用程序在本地主机和端口 9001 上运行 为了使我的应用程序更加安全并降低风险XSS ht
  • 如何在Android Studio中关联.mp3文件

    我想根据列表视图项单击播放 mp3 文件 但是根据我的代码 我运行我的应用程序 出现此窗口 因此由于缺少音频选项 我真的不知道需要选择其中哪一个为了关联我的 mp3 文件 mainList setOnItemClickListener ne
  • 摆动刷新周期

    我试图了解何时使用重新验证 重绘 打包 令人惊讶的是 我没有找到详细的底层文档 请随意链接 到目前为止我已经明白这都是 RepaintManager 的责任 油漆 重新油漆指的是脏 干净的东西 pack validate revalidat
  • Java 通用问题

    下面的代码可以编译 但如果我取消注释行 它不会编译 我很困惑为什么 HashMap 确实扩展了 AbstractMap 并且声明映射的第一行可以正常编译 import java util AbstractMap import java ut
  • 如何根据服务器/环境动态加载服务器配置?

    目前 我设置了 Maven 配置文件 以便能够为不同的环境 开发 演示 暂存 生产等 部署我的项目 并且它工作得很好 但问题是 对于我拥有的每个模块 Web 应用程序 我需要复制 粘贴此配置文件 它们都是属性文件 当我需要更改环境 服务器配
  • 在 Java Jersey 2 JAX-RS 中初始化单例

    我是泽西岛 2 22 2 的新手 请耐心等待 我正在创建一个与 LDAP 服务器交互的 REST 服务 用于存储 删除和检索用户数据 该服务通过执行加密 解密充当安全中介 在使用 REST 服务之前必须进行相当多的初始化 并且我只想执行此初
  • Jersey bean 验证 ParameterNameProvider

    我正在阅读关于泽西岛的文档Bean验证 https jersey java net documentation latest bean validation html The ParameterNameProvider示例显示如何定义方法的
  • bean 中的 Spring JavaConfig 属性未设置?

    我正在考虑将 Spring JavaConfig 与一些属性文件一起使用 但 bean 中的属性未设置 bean 中的属性未设置 这是我的网络配置 Configuration EnableWebMvc PropertySource valu
  • 警告:无法加载 sqljdbc_auth.dll 原因:java.library.path 中没有 sqljdbc_auth

    我正在使用 Ubuntu 12 05 并尝试连接到 Windows Server 2012 来获取数据库 我的数据库名称是 jobs 电脑的IP地址是192 160 1 33 托管在1433 但是当我尝试连接时出现以下错误 WARNING
  • LinkedBlockingQueue 抛出 InterruptedException

    我有这段代码 ALinkedBlockingQueue应该只抛出一个Exception如果在等待添加到队列时被中断 但这个队列是无限的 所以它应该尽快添加 为什么我的关闭方法会抛出一个InterruptedException private
  • 在私有 guice 模块中公开 Map

    我在 guice 中有一个 PrivateModule 我想从该模块公开一个 Map public class TestInjectionModule extends PrivateModule expose Map class annoa
  • 如何获取 EC2 实例的 CloudWatch 指标数据

    我想获取我的 EC2 实例的 Cloudmetrics 数据 以便我可以使用这些数据绘制图表并将其显示在我的 Android 设备上 我怎么做 有相同的示例程序或教程吗 提前致谢 这就是我正在做的 private static void f

随机推荐

  • 【Docker镜像】使用Dockerfile构建Docke容器镜像

    Docker镜像 使用Dockerfile构建Docke容器镜像 一 Docker镜像介绍 1 1 docker镜像简介 1 2 docker镜像特点 二 容器镜像的组成介绍 2 1 镜像的分层介绍 2 2 Docker的镜像分层示意图 三
  • Maven工程打包报错:Could not transfer artifact (https://repo.maven.apache.org/maven2): Received fatal alert

    报错信息为 Could not transfer artifact https repo maven apache org maven2 Received fatal alert protocol v 我用的jdk版本是1 7 是因为jdk
  • 亿级大表分库分表实战总结(万字干货,实战复盘)

    亿级大表分库分表实战总结 万字干货 实战复盘 以下文章来源于阿丸笔记 作者阿丸笔记 阿丸笔记 分库分表的文章网上非常多 但是大多内容比较零散 以讲解知识点为主 没有完整地说明一个大表的切分 新架构设计 上线的完整过程 因此 我结合去年做的一
  • 【Qt 菜单和二级菜单的加入和删除】

    QMenu MainMenu new QMenu this QAction option new QAction MainMenu actionList lt
  • 可加密解密的MD5算法

    public class MD5andKL MD5加码 32位 public static String MD5 String inStr MessageDigest md5 null try md5 MessageDigest getIn
  • 【SpringBoot高级篇】SpringBoot项目部署到docker环境中

    SpringBoot高级篇 SpringBoot项目部署到docker环境中 idea手动部署 1 创建springboot项目 1 1 POM xml 1 2 Controller 1 3 appplication yml 2 打包spr
  • eclipse debug后new 菜单只有 Project 、Example 、 Other 没有Java Project 、Package 、Class等的解决方法

    eclipse debug后new 菜单只有 Project Example Other 没有Java Project Package Class等的解决方法 解决办法 切换工作空间
  • 2023网安人才报告:网络安全科技人才市场需求规模快速增长

    7月24日 奇安信行业安全研究中心联合牛客平台 网教盟 新安盟 广州大学 深圳信息职业技术学院等单位 在BCS2023重庆网络与数据安全产业大会上共同发布了 2023网络安全人才市场状况研究报告 报告显示 在过去一年中 网络安全科技人才市场
  • 如何把文件传到华为云服务器,如何把文件传到云服务器

    如何把文件传到云服务器 内容精选 换一换 本节为您介绍如何在本机使用远程登录工具MSTSC登录Windows弹性云服务器 弹性云服务器状态为 运行中 如果弹性云服务器采用密钥方式鉴权 已获取Windows弹性云服务器的密码 获取方式请参见获
  • 电脑主板跳线_电脑哥教你如何接电脑主板跳线

    主板跳线接法详解 图 作为一名新手 要真正从头组装好自己的电脑并不容易 也许你知道CPU应该插哪儿 内存应该插哪儿 但遇到一排排复杂跳线的时候 很多新手都不知道如何下手 钥匙开机其实并不神秘 还记不记得你第一次见到装电脑的时候 JS将CPU
  • stm32f407 usb cdc设备无法启动问题

    最新要做一个项目 要求基于STM32F407实现USB CDC设备 首先想到的就是直接用STM32CUBEMX工具来生成 OK 话不多说 直接上过程 RCC配置 Sys配置 USB OTG FS配置 USB DEVICE配置 时钟配置 然后
  • Windows 下安装并配置Maven

    前言 Maven 翻译为 专家 内行 是Apache下的一个纯Java开发的开源项目 Maven 是一个项目管理工具 可以对Java项目进行构建 依赖管理 Maven是基于项目对象模型 POM project object model 可以
  • 输入阻抗与偏置电流

    对于高阻信号要选用FET运放 高阻信号R2和运放上的高阻并联会影响实际R2电阻值 CMRR 共模抑制比 放大电路对差模信号的电压增益与对共模信号的电压增益之比的绝对值 因为我们要抑制零漂所以共模电压增益越小越好 而差模电压增益越大越好 所以
  • pycharm上已存在某些库,但无法调用的问题解决

    如果出现pycharm上已存在openpyxl 但无法调用的时候 就是pycharm安装openpyxl库时 安装的位置与pycharm中引用python解释器的位置不一致 导致不能调用opentyxl 所以再安装openpyxl时 把项目
  • Python 绝对简明手册

    原文 简述 1 阅读须知 文中使用 gt gt gt 作为会命令行中的输出信息的前缀 对于不清楚用用途的函数可以在解释器下面输入 help 函数名 来获取相关信息 另外 自带的文档和google也是不可少的 2 基本语法 2 1 if el
  • 简历制作讲解

    简历制作讲解 前期假想 简历如同一本书 书大体分为文本结构和文本内容 一 简历文本结构 一 个人信息 必要 二 教育背景 必要 三 自我介绍 可选 四 工作经历 五 项目经历 六 技能评价 二 简历文本内容 一 个人信息 必要 必要信息 姓
  • WebTestClient使用

    介绍 WebTestClient用于测试WebFlux服务器端点的主要入口点 它具有与WebClient非常相似的API 内部大部分调用WebClient实例 主要提供测试上下文 绑定到一个服务 WebTestClient testClie
  • 解决:参考的对象类型不支持尝试的操作。 [已退出进程,代码为 4294967295]

    问题描述 win10系统下运行wsl时候显示错误 参考的对象类型不支持尝试的操作 已退出进程 代码为 4294967295 经过个人测试解决方式为关闭网易UU当前的加速 过一会就恢复正常 不需要重启
  • MySQL架构的Server层的执行过程

    1 连接器 主要负责跟客户端建立连接 获取权限 维持和管理连接 2 查询缓存 优先在缓存中进行查询 如果查到了则直接返回 如果缓存中查询不到 在去数据库中查询 3 解析器 分析器 分析器的工作主要是对要执行的SQL语句进行词法解析 语法解析
  • 基于SpringBoot+Async注解整合多线程

    提示 本文没有使用原生的创建线程方式 默认已掌握创建线程的四种方式 全文基于SpringBoot框架 要求读者掌握SpringBoot操作 本人能力有限 如有遗漏或错误 敬请指正 谢谢 文章目录 其他文章 前言 一 为什么要使用多线程 二