spring boot 中的异步@Async

spring boot 开启异步调用

1、启动类上添加@EnableAsync注解,表示启动异步

2、在具体实现异步的方法上添加@Async注解

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}
package com.example.demo;


import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * @Description: TODO
 * @author: sl
 * @date: 2024年05月30日 21:55
 */
@Component
public class DemoController {

     /**
     *  Async相当于是方法级别的线程,本身没有自定义线程池更加灵活
     *  相当于是每进来一个请求就开启一个线程,超过核心线程数小于最大线程数放入队列,
     *  队列满了,继续创建线程直至达到最大线程数
     * @throws InterruptedException
     */
    @Async
    public void testSync() throws InterruptedException {
        Thread.sleep(2000);
        System.out.println("异步执行成功");
    }
}

测试执行 

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    private DemoController demoController;

    @Test
    void contextLoads() throws InterruptedException {
        demoController.testSync();
        System.out.println("主线程执行");
        Thread.sleep(4000);
    }

}

执行结果 

执行原理

SpringBoot会默创建了一个线程池,使用这里面的线程来执行异步调用,在项目中使用

手动创建线程池异步调用 

常用线程池创建以及弊端

Executors 是一个 Java 中的工具类。提供四种线程池创建方式,工厂方法来创建不同类型的线程池。Executors 的创建线程池的方法,创建出来的线程池都实现了ExecutorService 接口,

1.newFiexedThreadPool(int Threads):创建固定数目线程的线程池。
2.newCachedThreadPool():创建一个可缓存的线程池,调用 execute将重用以前构造的线程(如果线程可用)。如果没有可用的线程,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
3.newSingleThreadExecutor() 创建一个单线程化的 Executor。
4.newScheduledThreadPool(int corePoolSize) 创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代 Timer 类

不建议大家使用Executors这个类来创建线程池呢,阿里开发手册这样定义:
强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式

Executors 返回的线程池对象的弊端如下:

1) FixedThreadPool 和 SingleThreadPool:

允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致 OOM

2) CachedThreadPool 和 ScheduledThreadPool:

允许的创建线程数量为 Integer.MAX_VALUE, 可能会创建大量的线程,从而导致 OOM

使用常见的三种线程池创建方式,单一、可变、定长都有一定问题,原因是 FixedThreadPool 和 SingleThreadExecutor 底层都是用LinkedBlockingQueue 实现的,这个队列最大长度为 Integer.MAX_VALUE,容易导致 OOM
所以实际生产一般自己通过 ThreadPoolExecutor 的 7 个参数,自定义线程池

spring boot创建线程池 

springboot创建线程池,Spring提供的对ThreadPoolExecutor封装的线程池ThreadPoolTaskExecutor,直接使用注解启用。
Async相当于是方法级别的线程,本身没有自定义线程池更加灵活

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Description: TODO
 * @author: sl
 * @date: 2024年05月30日 22:37
 */
@Configuration
public class MyPoolConfig {
    @Bean
    public TaskExecutor taskExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //设置核心线程数
        executor.setCorePoolSize(10);
        //设置最大线程数
        executor.setMaxPoolSize(15);
        //设置队列容量
        executor.setQueueCapacity(20);
        //设置线程活跃时间(秒)
        executor.setKeepAliveSeconds(60);
        //设置默认线程名称
        executor.setThreadNamePrefix("1111-");
        //设置拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        return executor;
    }

}

在Async中指定线程池

package com.example.demo;


import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * @Description: TODO
 * @author: sl
 * @date: 2024年05月30日 21:55
 */
@Component
public class DemoController {

    /**
     *  Async相当于是方法级别的线程,本身没有自定义线程池更加灵活
     *  相当于是每进来一个请求就开启一个线程,超过核心线程数小于最大线程数放入队列,
     *  队列满了,继续创建线程直至达到最大线程数
     * @throws InterruptedException
     */
    @Async("taskExecutor")
    public void testSync() throws InterruptedException {
        System.out.println(Thread.currentThread().getName());
        Thread.sleep(2000);
        System.out.println("异步执行成功");
    }
}

执行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/664208.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

rtos最小任务切换的实现 keil软件仿真 stm32 PendSV

最小任务切换的实现 本例子实现了一个 rtos 最小的任务切换功能,使用 keil 仿真功能,在模拟的 stm32f103 的器件上实现了使用 PendSV 中断切换线程的效果。 git 源码仓库:https://github.com/yutianos/rtos-little 本文链接:csdn…

时钟、复位与上电初始化

目录 1. 复位2.1. 异步复位 同步释放2.2. Xilinx FPGA复位设计尽量少用复位reg信号初始值基于PLL锁定(locked)复位设计 2. 时钟 1. 复位 FPGA中复位设计总结 深入理解复位—同步复位,异步复位,异步复位同步释放(含多时钟域&#x…

认识Oracle v$mystat视图

v$mystat就是当前用户的各种统计信息, sid就是session的id(也就是当前用户),STATISTIC#就是统计量的编号(用来唯一确定统计量的名称),value是统计量的值; desc命令在Oracle中通常用于查看表结构; v$mystat视图中只会有当前用户…

pdf拆分成有图和无图的pdf(方便打印)

pdf拆分成有图和无图的pdf(方便打印) 原因 打印图片要彩印,每次都要手动弄,打印的时候很麻烦; 随着打印次数的增加,时间就越来越多 为解决此问题,使用python写一个exe解决这个问题 历程 找一个python的GUI界面找到 t…

Python 机器学习 基础 之 算法链与管道 【通用的管道接口/网格搜索预处理步骤与模型参数/网格搜索选择使用哪个模型】的简单说明

Python 机器学习 基础 之 算法链与管道 【通用的管道接口/网格搜索预处理步骤与模型参数/网格搜索选择使用哪个模型】的简单说明 目录 Python 机器学习 基础 之 算法链与管道 【通用的管道接口/网格搜索预处理步骤与模型参数/网格搜索选择使用哪个模型】的简单说明 一、简单介…

Linux前奏-预热版本

一、操作系统概述 1.1 了解操作系统的作用 我们所熟知的计算机,也就是电脑,就是由硬件和软件来组成的 硬件:计算机系统中由电子机械,和各种光电元件等组成的各种物理装置的总称 软件是什么呢? 软件:用…

视频汇聚平台EasyCVR对接GA/T 1400视图库结构化数据:人员/人脸、非/机动车、物品

在信息化浪潮席卷全球的背景下,公安信息化建设日益成为提升社会治理能力和维护社会稳定的关键手段。其中,GA/T 1400标准作为公安视频图像信息应用系统的核心规范,以其结构化数据处理与应用能力,为公安信息化建设注入了强大的动力。…

skywalking介绍及搭建

链路追踪框架比对: skywalking安装部署: 下载地址:Downloads | Apache SkyWalking 配置微服务与skywalking整合: copy agent/optional-plugins/apm-spring-cloud-getway-xx.jar到plugins,然后重启skywalking 监控界面…

基于开源项目ESP32 SVPWM驱动无刷电机开环速度测试

基于开源项目ESP32 SVPWM驱动无刷电机开环速度测试 ✨本篇硬件电路和代码来源于此开源项目:https://github.com/MengYang-x/STM3F401-FOC/tree/main📍硬件电路和项目介绍,立创开源广场:https://oshwhub.com/shadow27/tai-yang-nen…

Web程序设计-实验05 DOM与BOM编程

题目 【实验主题】 影视网站后台影视记录管理页设计 【实验任务】 1、浏览并分析多个网站后台的列表页面、编辑页面(详见参考资源,建议自行搜索更多后台页面)的主要元素构成和版面设计,借鉴并构思预期效果。 2、新建 index.h…

pycharm 上一次编辑位置不见了

目录 pycharm2024版 上一次编辑位置不见了,研究发现移到了左下角了,如下图所示: 上一次编辑位置快捷键: pycharm2024版 上一次编辑位置不见了,研究发现移到了左下角了,如下图所示: 上一次编辑…

在IDEA中使用Git在将多次commit合并为一次commit

案例: 我想要将master分支中的 测试一、测试二、测试三三次commit合并为一次commit 1. 点击Git 2. 双击点击commit所在的分支 3. 右键要合并的多个commit中的第一次提交的commit 4. 点击右键后弹出的菜单中的Interactively Rebase From Here选项 5. 点击测试二…

elementui el-tooltip文字提示组件弹出层内容格式换行处理

1、第一种 1.1 效果图 1.2、代码 <template><div class"wrapper"><el-tooltip class"content" effect"dark" placement"top"><div slot"content"><div v-html"getTextBrStr(text)"&…

数据可视化:解析其在现代生活中的日益重要地位

数据可视化为什么对我们的生活影响越来越大&#xff1f;这是一个值得探讨的话题。在信息化时代&#xff0c;数据无处不在&#xff0c;海量的数据不仅改变了商业模式&#xff0c;也深刻影响了我们的日常生活。数据可视化作为一种将复杂数据转化为直观图表、图形的技术&#xff0…

CLIP模型NAN问题解决

早有耳闻&#xff0c;clip模型会在fp16下发生NAN的问题&#xff0c;但是今天基于2080Ti测试&#xff0c;发现在单精度下的tensorrt推理同样存在NAN的问题&#xff0c;我甚至一度怀疑是tensorrt的推理代码有问题。 之后&#xff0c;决定从python代码的角度去寻找问题的答案&…

PostgreSQL常用插件

PostgreSQL 拥有许多常用插件&#xff0c;这些插件可以大大增强其功能和性能。以下是一些常用的 PostgreSQL 插件&#xff1a; 性能监控和优化 pg_stat_statements 1.提供对所有 SQL 语句执行情况的统计信息。对调优和监控非常有用。 2.安装和使用&#xff1a; pg_stat_k…

SOLIDWORKS参数化开发 慧德敏学

传统的设计模式下大规模定制型产品结构设计周期长&#xff0c;问题多&#xff0c;以及大量重复性工作让工程师疲于应对&#xff0c;这些严重阻碍了公司订单承接能力和技术创新能力&#xff0c;难以响应市场需求。 什么是参数化设计&#xff1f; 1、它是一种设计的方式&#x…

oracle mysql索引区别

文章目录 1.引言1.1 索引的基本概念1.2 Oracle和MySQL的简介 2.Oracle索引2.1 Oracle索引的类型**B-Tree索引****Bitmap索引****Function-Based索引****Partitioned索引****Text索引** 2.2 Oracle索引的工作原理2.3 Oracle索引的实例代码 3.MySQL索引3.1 MySQL索引的类型**B-Tr…

Linux开发工具(个人使用)

Linux开发工具 1.Linux yum软件包管理器1.1Linux安装程序有三种方式1.2注意事项1.3如何查看&#xff0c;安装&#xff0c;卸载软件包1.3.1查看软件包1.3.2安装软件包1.3.3卸载软件 2.Linux vim编辑器2.1vim的基本操作2.2vim正常模式命令集2.3vim底行模式命令集2.4vim配置 3.Lin…

imx6ull - 制作烧录SD卡

1、参考NXP官方的手册《i.MX_Linux_Users_Guide.pdf》的这一章节&#xff1a; 1、SD卡分区 提示&#xff1a;我们常用的SD卡一个扇区的大小是512字节。 先说一下i.MX6ULL使用SD卡启动时的分区情况&#xff0c;NXP官方给的镜像布局结构如下所示&#xff1a; 可以看到&#xff0c…