Spring Boot注解@Async与线程池的配置

news2025/1/29 3:22:10

目录

使用异步注解创建异步任务

@Async注解

使用Demo

线程池配置

Spring Boot默认用于异步任务线程池配置

 线程池配置

 线程池隔离

为什么需要线程池隔离?

线程池隔离实现Demo

 线程池配置:

 异步任务:

测试demo

参考内容:


使用异步注解创建异步任务

@Async注解

异步注解,需要在 springboot主程序上配置@EnableAsync。

使用条件:任务本身之间不存在依赖关系

使用Demo

@Component
@Slf4j
public class AsyncTasksService {

    public static Random random = new Random();

    @Async
    public CompletableFuture<String> doTaskOne() throws Exception {
        log.info("doTaskOne()开始");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("doTaskOne()执行结束,耗时:" + (end - start) + "毫秒");
        return CompletableFuture.completedFuture("doTaskOne()执行结束");
    }
    @Async
    public CompletableFuture<String> doTaskTwo() throws Exception {
        log.info("doTaskTwo()开始");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("doTaskTwo()执行结束,耗时:" + (end - start) + "毫秒");
        return CompletableFuture.completedFuture("doTaskTwo()执行结束");
    }
    @Async
    public CompletableFuture<String> doTaskThree() throws Exception {
        log.info("doTaskThree()开始");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("doTaskThree()执行结束,耗时:" + (end - start) + "毫秒");
        return CompletableFuture.completedFuture("doTaskThree()执行结束");
    }
}
@SpringBootTest
@Slf4j
@RunWith(SpringRunner.class)
public class AsyncTasksTest {
    @Resource
    private AsyncTasksService asyncTasksService;
    @Test
    public void test() throws Exception {
        long start = System.currentTimeMillis();

        CompletableFuture<String> task1 = asyncTasksService.doTaskOne();
        CompletableFuture<String> task2 = asyncTasksService.doTaskTwo();
        CompletableFuture<String> task3 = asyncTasksService.doTaskThree();

        CompletableFuture.allOf(task1, task2, task3).join();

        long end = System.currentTimeMillis();

        log.info("任务全部完成,总耗时:" + (end - start) + "毫秒");
    }
}

 测试结果:

11:02:20.078 [task-3] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskThree()开始
11:02:20.078 [task-1] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskOne()开始
11:02:20.078 [task-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskTwo()开始
11:02:24.453 [task-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskTwo()执行结束,耗时:4375毫秒
11:02:26.571 [task-1] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskOne()执行结束,耗时:6493毫秒
11:02:27.570 [task-3] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskThree()执行结束,耗时:7492毫秒
11:02:27.571 [main] INFO  com.springwork.high.AsyncTasksTest - 任务全部完成,总耗时:7500毫秒

线程池配置

为了控制异步任务的并发不影响到应用的正常运作,我们必须要对线程池做好相应的配置,防止资源的过渡使用

Spring Boot默认用于异步任务线程池配置

源码位置:org.springframework.boot.autoconfigure.task.TaskExecutionProperties

 线程池配置

spring:
  task:
    execution:
      pool:
        core-size: 8
        max-size: 5
        queue-capacity: 10
        keep-alive: 60s
        allow-core-thread-timeout: true
      shutdown:
        await-termination: false
        await-termination-period:
      thread-name-prefix: hightask-
task:
  execution:
    pool:
      core-size: 8 (线程池创建时的初始化线程数,默认为8)
      max-size: 5 (线程池的最大线程数,默认为int最大值,即(2^31)-1)
      queue-capacity: 10 (用来缓冲执行任务的队列,默认为int最大值,即(2^31)-1)
      keep-alive: 60s  (线程终止前允许保持空闲的时间)
      allow-core-thread-timeout: true (是否允许核心线程超时)
    shutdown:
      await-termination: false (是否等待剩余任务完成后才关闭应用)
      await-termination-period: (等待剩余任务完成的最大时间)
    thread-name-prefix: hightask- (线程名的前缀)

 配置线程池,并将初始化线程数改成2后结果:

15:11:00.786 [hightask-1] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskOne()开始
15:11:00.786 [hightask-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskTwo()开始
15:11:02.434 [hightask-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskTwo()执行结束,耗时:1648毫秒
15:11:02.434 [hightask-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskThree()开始
15:11:04.397 [hightask-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskThree()执行结束,耗时:1963毫秒
15:11:04.757 [hightask-1] INFO  com.springwork.high.asyncTasks.AsyncTasksService - doTaskOne()执行结束,耗时:3971毫秒
15:11:04.757 [main] INFO  com.springwork.high.AsyncTasksTest - 任务全部完成,总耗时:3979毫秒

 线程池隔离

为什么需要线程池隔离?

@Async创建的异步任务都是共用的一个线程池,当有一些异步任务碰到性能问题的时候,是会直接影响其他异步任务的。

线程池隔离实现Demo

 线程池配置:

package com.springwork.high.asyncTasks;



import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author gj
 * @version 1.0.0
 * @date 2023/5/26 15:25
 */
@EnableAsync
@Configuration
public class AsyncTasksPoolConfig {
    @Bean(name = "highExecutor1")
    public Executor asyncTaskExecutor1() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(10);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("high-1-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
    @Bean(name = "highExecutor2")
    public Executor asyncTaskExecutor2() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(10);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("high-2-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

 异步任务:

package com.springwork.high.asyncTasks;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Random;
import java.util.concurrent.CompletableFuture;

/**
 * @author gj
 * @version 1.0.0
 * @date 2023/5/26 10:17
 */
@Component
@Slf4j
public class AsyncTasksService {

    public static Random random = new Random();

    @Async("highExecutor1")
    public CompletableFuture<String> doTaskOne(String taskName) throws Exception {
        log.info("开始任务:"+taskName);
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("执行结束"+taskName+"耗时:" + (end - start) + "毫秒");
        return CompletableFuture.completedFuture("doTaskOne()执行结束");
    }
    @Async("highExecutor2")
    public CompletableFuture<String> doTaskTwo(String taskName) throws Exception {
        log.info("开始任务:"+taskName);
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("执行结束"+taskName+"耗时:" + (end - start) + "毫秒");
        return CompletableFuture.completedFuture("执行结束");
    }
}

测试demo

        CompletableFuture<String> task1 = asyncTasksService.doTaskOne("1");
        CompletableFuture<String> task2 = asyncTasksService.doTaskOne("2");
        CompletableFuture<String> task3 = asyncTasksService.doTaskOne("3");
        CompletableFuture<String> task4 = asyncTasksService.doTaskTwo("4");
        CompletableFuture<String> task5 = asyncTasksService.doTaskTwo("5");
        CompletableFuture<String> task6 = asyncTasksService.doTaskTwo("6");


        CompletableFuture.allOf(task1, task2, task3,task4,task5,task6).join();

测试结果:

 15:44:50.899 [high-1-1] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 开始任务:1
15:44:50.899 [high-2-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 开始任务:5
15:44:50.899 [high-1-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 开始任务:2
15:44:50.899 [high-2-1] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 开始任务:4
15:44:51.159 [high-1-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 执行结束2耗时:260毫秒
15:44:51.159 [high-1-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 开始任务:3
15:44:51.442 [high-1-1] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 执行结束1耗时:542毫秒
15:44:52.724 [high-1-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 执行结束3耗时:1564毫秒
15:45:00.414 [high-2-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 执行结束5耗时:9515毫秒
15:45:00.414 [high-2-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 开始任务:6
15:45:00.690 [high-2-1] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 执行结束4耗时:9791毫秒
15:45:00.764 [pool-2-thread-1] INFO  com.springwork.high.common.ScheduleTaskCommon - CurrentTime: 2023-05-26T15:45:00.764
15:45:08.855 [high-2-2] INFO  com.springwork.high.asyncTasks.AsyncTasksService - 执行结束6耗时:8440毫秒
15:45:08.856 [main] INFO  com.springwork.high.AsyncTasksTest - 任务全部完成,总耗时:17964毫秒

参考内容:

http://t.csdn.cn/Drzb4

http://t.csdn.cn/9usjv

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动态优化会议地点

前言 在现在快节奏的工作节奏下&#xff0c;大家的活动范围越来越广&#xff0c;但是出行成本也相应提高。在集体会面的时候&#xff0c;如何选择合适的地点成为了一个棘手的问题。本文将介绍如何通过动态优化选择会议地点&#xff0c;以达到平均交通成本最低的目标。 动态优化…

【操作系统真象还原】第4章:保护模式入门(4.4~4.5节)

目录 4.4 处理器微架构简介 4.4.1 流水线 4.4.2 乱序执行 4.4.3 缓存 4.4.4 分支预测 4.5 使用远跳转指令清空流水线&#xff0c;更新段描述符缓冲寄存器 4.6 保护模式之内存段的保护 4.6.1 向段寄存器加载选择子时的保护 4.6.2 代码段和数据段的保护 4.6.3 栈段的保…

CentOS7 网络配置

在Linux系统下 查询CentOS7的ip地址 输入ip查询命名 ip addr 也可以输入 ifconfig查看ip&#xff0c;但此命令会出现3个条目&#xff0c; centos的ip地址是ens33条目中的inet值。 输入命令: ip addr 结果如下: 使用: ifconfig 命令查询结果如下: 发现 ens33 没有 inet 这个属性…

国内半导体分立器件逐步向高端应用市场推进,未来可期

分立器件行业概况 半导体分立器件是半导体产业的基础及核心领域之一&#xff0c;其具有应用领域广阔、高成品率、特殊器件不可替代等特性。 从市场需求看&#xff0c;分立器件受益于物联网、可穿戴设备、智能家居、健康护理、安防电子、新能源汽车、智能电网、5G通信射频等市…

如何在华为OD机试中获得满分?Java实现【云短信平台优惠活动】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述4. Java算法源码5. 测试6.解题思路1. 题目描述 某云短信厂商,为庆祝国…

如何建立自己的微信小程序,做一个微信小程序大概多少钱?

如今&#xff0c;小程序的功能越来越强大&#xff0c;也越来越受欢迎&#xff0c;它不仅能帮助企业和商家做推广&#xff0c;还能给他们带来很多好处。所以&#xff0c;很多企业都开始建立自己的小程序。但是对于如何建立自己的微信小程序&#xff0c;以及做一个微信小程序大概…

Zemax Lumerical | 二维光栅出瞳扩展系统优化

简介 本文提出并演示了一种以二维光栅耦出的光瞳扩展&#xff08;EPE&#xff09;系统优化和公差分析的仿真方法。 在这个工作流程中&#xff0c;我们将使用3个软件进行不同的工作 &#xff0c;以实现优化系统的大目标。首先&#xff0c;我们使用 Lumerical 构建光栅模型并使用…

基于C++的网盘系统项目开发教程

项目资源下载 基于C的网盘系统项目源码CSDN下载地址基于C的网盘系统项目源码GitHub下载地址 项目简介 本项目基于C开发&#xff0c;整个项目采用C/S架构&#xff0c;使用Sqlite3数据库存储用户信息&#xff0c;本地磁盘存储用户文件&#xff0c;使用Socket进行客户端和服务器之…

智能指针: share_ptr(共享智能指针)

智能指针 c中不像java自带垃圾回收机制&#xff0c;必须释放掉分配的内存&#xff0c;否则机会造成内存泄漏。因此c11加入了智能指针。智能指针是存储指向动态分配&#xff08;堆&#xff09;对象指针的类&#xff0c;用于生存期的控制&#xff0c;能够确保在离开指针所在作用…

Selenium4自动化框架(超级详细)

目录 Selenium4 安装Selenium 安装浏览器驱动 实战案例 导入模块及浏览器驱动 导入模块 启动驱动 定位元素 id、name、class定位 tag_name定位 xpath定位 css选择器定位 link_text、partial_link_text定位 其他定位 定位一组元素 执行操作 浏览器操作 获取信息…

1. 自然语言处理NLP-数据预处理

NLP任务预处理的流程包括&#xff1a; 收集语料库、文本清洗、分词、去掉停用词、标准化和特征提取等。 &#xff08;1&#xff09;收集语料库 &#xff08;2&#xff09;清洗数据 eg&#xff1a;删除所有不相关的字符&#xff0c;例如非字母数字字母 &#xff08;3&#xff09…

Java Servlet相关面试题

一、什么是servlet&#xff1f; Servlet是运行在java服务器中的小型Java程序。 作用&#xff1a;接收用户请求&#xff0c;并对请求作出处理&#xff0c;将处理结果相应给客户端。 Servlet是JavaWeb三大组件&#xff08;Servlet、过滤器&#xff0c;监听器 &#xff09;之一…

C++学习day--12 循环

第 1 节: 需求分析、项目实现——重复验证 项目实现&#xff1a; #include <iostream> #include <Windows.h> #include <string> using namespace std; int main(void) { string name; string pwd; while (1) { system("cls"); std::cout <…

Windows编辑开发中的内聚性、内聚类型、耦合性和耦合类型

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天总结一下Windows编辑开发中的内聚性、内聚类型、耦合性和耦合类型。 软件设计的基本原则是信息隐蔽性与模块独立性。 模块设计目标是高内聚&#xff0c;低耦合。 然后记住下面这张神图&#xff0c;一张…

Mybatis之MetaObject

在mybatis中&#xff0c;ResultSetHandler在收集JDBC返回的结果后需要转换成对应的Bean对象&#xff0c;其实映射的原理基本大家都能想到使用的时候java中的反射机制&#xff0c;但是在Mybatis中&#xff0c;提供了一个更加强大的对象&#xff0c;就是MetaObject&#xff0c;使…

Python - 面向对象编程 - 实例方法、静态方法、类方法

实例方法 在类中定义的方法默认都是实例方法&#xff0c;前面几篇文章已经大量使用到实例方法 实例方法栗子 class PoloBlog:def __init__(self, name, age):print("自动调用构造方法")self.name nameself.age agedef test(self):print("一个实例方法&…

阿里P8写出的《深入理解Java虚拟机》最新版,轻松学会JVM底层

前言 Java是目前用户最多、使用范围最广的软件开发技术&#xff0c;Java的技术体系主要由支撑Java程序运行的虚拟机、提供各开发领域接口支持的Java类库、Java编程语言及许许多多的第三E方Java框架(如Spring、 MyBatis等) 构成。在国内&#xff0c;有关Java类库API、Java语言语…

能源汽车下乡充电桩建设优化建议及解决方案

安科瑞 耿敏花 摘 要&#xff1a;5月5日&#xff0c;国务院总理李强主持召开国务院常务会议&#xff0c;审议通过关于加快发展先进制造业集群的意见&#xff0c;部署加快建设充电基础设施&#xff0c;更好支持新能源汽车下乡和乡村振兴。 会议指出&#xff0c;农村新能源汽车市…

JavaScript 原型和原型链

文章目录 JavaScript 原型和原型链概述new操作符的流程原型对象、构造函数、实例关系原型链原型链查找hasOwnPropertyin JavaScript 原型和原型链 概述 任何函数都有prototype属性&#xff0c;prototype是原型的意思。 prototype的属性值是个对象&#xff0c;它默认拥有cons…

Java内存模型(Java Memory Mode,JMM)

并发编程模型的两个关键问题 线程之间如何通信及线程之间如何同步。 线程之间如何通信&#xff1a;共享内存&#xff0c;消息传递线程之间如何同步通信是指线程之间以何种机制来 交换信息同步是指程序中用于控制不同线程间 操作发生相对顺序 的机制在共享内存的并发模型里&a…