在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异步参数。根据你自己的情况进行选择。

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Miaow.Y.Hu

赏一口饭吃吧,大大们

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值