当前位置: 首页 > article >正文

在Spring Boot中使用@Async异步任务的线程池

在读这篇文章之前,我们先回答一个问题,什么是并发,并发和多线程是什么关系?

并发是指系统中存在多个独立的活动(任务、线程等),这些活动在一段时间内交替执行,从而使得多个活动在重叠的时间段内存在。在计算机科学中,通常指的是同时处理多个任务的能力。这些任务可能是同时运行的独立进程、线程或通过时间片轮转的方式交替执行。

多线程是实现并发的一种方式。在一个进程中,可以创建多个线程,每个线程执行一个独立的任务。这些线程共享相同的进程资源,如内存空间,但每个线程有自己的程序计数器、栈和局部变量。多线程使得程序能够同时执行多个任务,提高了系统的资源利用率和响应速度。

并发和多线程之间存在密切关系多线程是一种实现并发的方式,通过同时运行多个线程,可以在同一时间内执行多个任务,从而实现并发。在并发系统中,多线程可以同时处理多个任务,使得系统更加高效、灵活和响应性强。然而,要确保多线程的正确执行,需要注意线程之间的同步、互斥和共享资源的管理,以避免潜在的竞态条件和数据一致性问题。


那么我们来说说,既然有了@Async,我们还需要使用他提供的线程池?

虽然使用@Async注解允许方法异步执行,但它并不提供底层的线程池管理。默认情况下,Spring会使用一个简单的任务执行器来执行异步方法,这可能不是在所有场景下都是理想的。

  1. 自定义线程池配置:使用@Async注解时候,默认情况相爱,我们Spring 使用的是SimpleAsyncTaskExecutor,这个执行器每次都会创建一个新的线程来执行任务,这也可能并非在我们所有的情况下都是最佳的选择,我们可以通过@Async提供的线程池,可以通过配置线程池的大小,队列容量,线程命名等,可以满足我们的应用程序的需求。
  2. 线程池的管理和监控: @Async提供的线程池是一个ThreadPoolTaskExecutor,它是TaskExecutor接口的实现。这使得可以更容易地与Spring的其他任务调度和执行功能进行集成,例如与@Scheduled注解一起使用。此外,Spring提供了对线程池的监控和管理的支持,你可以在Spring的JMX(Java Management Extensions)中监视和管理线程池的运行状况。
  3. 任务拒绝策略: 通过使用@Async提供的线程池,你可以配置任务拒绝策略来处理在线程池已满时提交的任务。这允许你在高负载情况下更好地控制任务的流量,防止系统过载。
  4. 更好的性能和资源利用: 通过使用合适配置的线程池,可以更好地控制线程的数量,防止系统过度消耗资源。线程池的管理机制可以有效地重用线程,减少线程创建和销毁的开销。

接下来我们来看一下一个案例:


配置一个线程池,以控制异步任务的执行。在你的Spring Boot应用程序的配置类中,添加@Bean注解的方法,返回TaskExecutor类型的bean。

@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean(name = "asyncExecutor")
    public TaskExecutor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5); // 设置核心线程池大小
        executor.setMaxPoolSize(10); // 设置最大线程池大小
        executor.setQueueCapacity(100); // 设置队列容量
        executor.setThreadNamePrefix("AsyncThread-"); // 设置线程名前缀
        executor.initialize();
        return executor;
    }
}

创建一个Service类:

@Service
public class AnotherService {

    private final MyAsyncService myAsyncService;

    @Autowired
    public AnotherService(MyAsyncService myAsyncService) {
        this.myAsyncService = myAsyncService;
    }

    public void performAsyncTask() {
        myAsyncService.asyncMethod();
        myAsyncService.asyncMethod();
        myAsyncService.asyncMethod();
        myAsyncService.asyncMethod();
        myAsyncService.asyncMethod();
        // 其他逻辑
    }
}

在上边asyncExecutor方法返回一个ThreadPoolTaskExecutor实例。


服务类或组件中,使用@Async注解标记异步方法

@Service
public class MyAsyncService {

    @Async
    public void asyncMethod() {
        // 异步任务的实现
        System.out.println("Async method executed by thread: " + Thread.currentThread().getName());
    }
}

之后我们创建一个单元测试来测试一下:

@Slf4j
@SpringBootTest
public class ApplicationTests {



    @Autowired
    private AnotherService anotherService;

    @Test
    public void test1() throws Exception {
        anotherService.performAsyncTask();
    }

}

在这里插入图片描述

看一下Anysc的相关参数
在这里插入图片描述

有关于参数,我这里进行详细介绍一下:

	private final Object poolSizeMonitor = new Object();
    private int corePoolSize = 1;
    private int maxPoolSize = Integer.MAX_VALUE;
    private int keepAliveSeconds = 60;
    private int queueCapacity = Integer.MAX_VALUE;
    private boolean allowCoreThreadTimeOut = false;
    @Nullable
    private TaskDecorator taskDecorator;
    @Nullable
    private ThreadPoolExecutor threadPoolExecutor;
    private final Map<Runnable, Object> decoratedTaskMap;

poolSizeMonitor

类型:Object
说明:这是一个监视线程池大小的对象。在代码中,使用 synchronized 块来确保对线程池大小的修改是线程安全的。

corePoolSize

类型:int
默认值:1
说明:核心线程池大小,即线程池中保持存活的线程数量。这些线程在没有任务执行时仍然存活,减少了线程的创建和销毁开销。

maxPoolSize

类型:int
默认值:Integer.MAX_VALUE
说明:线程池中允许的最大线程数。当核心线程都在忙于执行任务且队列已满时,新任务将创建额外线程,但数量不超过 maxPoolSize。

keepAliveSeconds

类型:int
默认值:60
说明:非核心线程的闲置时间超过此值时,线程将被终止。这有助于控制线程池的大小,避免过多的线程资源占用。

queueCapacity

类型:int
默认值:Integer.MAX_VALUE
说明:任务队列的容量,用于保存等待执行的任务。当所有核心线程都在忙于执行任务时,新任务将被放入队列中等待。

allowCoreThreadTimeOut

类型:boolean
默认值:false
说明:确定核心线程是否也可以因为闲置超时而被终止。如果设置为true,即使核心线程在执行任务之后处于空闲状态,它们也可能被终止。

taskDecorator

类型:TaskDecorator
默认值:null
说明:任务装饰器,用于在将任务提交到线程池之前修改任务的行为。可以用于记录任务执行时间、添加上下文信息等。

threadPoolExecutor

类型:ThreadPoolExecutor
说明:实际的 ThreadPoolExecutor 实例。在运行时,这个字段可能会被初始化为ThreadPoolExecutor 的实例,用于执行异步任务。

decoratedTaskMap

类型:Map<Runnable, Object>
说明:装饰过的任务的映射。这可能用于跟踪已提交的任务及其状态。

我们可以利用以上的参数配置我们的@Async异步参数。根据你自己的情况进行选择。


http://www.kler.cn/a/147265.html

相关文章:

  • python 多进程,程序运行越来越慢踩坑
  • 风电电力系统低碳调度论文阅读第一期
  • GRE做题笔记(零散的个人经验)
  • 如何知道表之间的关系(为了知识图谱的构建)
  • 8.C++面向对象5(实现一个较为完善的日期类)
  • C:原反补码
  • Selenium 连接到现有的 Firefox 示例
  • C语言--每日选择题--Day27
  • buuctf web [极客大挑战 2019]PHP
  • app分发平台应用费用一般要怎么评估的?
  • diffusion model (九) EmuEdit技术小结
  • Docker-简介、基本操作
  • Langchain-Chatchat学习
  • [vxe-table] vxe-table-column配合v-if导致列样式与位置错乱
  • 文章解读与仿真程序复现思路——电力系统保护与控制EI\CSCD\北大核心《基于深度强化学习的城市配电网多级动态重构优化运行方法》
  • 学习c#的第二十四天
  • 最近数据分析面试的一点感悟...
  • 聚观早报 |魅族21搭载超声波指纹2.0;华为长安成立新公司
  • 研习代码 day42 | 动态规划——买卖股票的最佳时机 I II
  • unity学习笔记10
  • CF 1900B Laura and Operations 学习笔记
  • ETL+BI结合的数据集成工具
  • 了解FastSam:一个通用分割模型(草记)
  • 20231124给RK3399的挖掘机开发板在Andorid10下加鼠标右键返回
  • vue中的keep-alive详解与应用场景
  • 【React】useReducer