Spring Boot 中通过 TaskExecutor 来实现异步任务

简介

Spring 通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用 ThreadPoolTaskExecutor 可实现一个基于线程池的 TaskExecutor。而实际开发中任务一般是非阻碍的,即异步的,所以我们要在配置类中通过 @EnableAsync 开启对异步任务的支持,并通过在实际执行的 Bean 的方法中使用 @Async 注解来声明其是一个异步任务。

代码示例

配置类

在配置类中,利用 @EnableAsync 注解,开启对异步任务支持。配置类实现 AsyncConfigurer 接口,并重写 getAsyncExecutor() 方法,返回一个 ThreadPoolTaskExecutor,这样子我们就获得了一个基于线程池的 TaskExecutor

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@Configuration  // 声明是一个配置类
@EnableAsync    //开启异步的支持
public class TaskExecutorConfig implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {    //配置类实现 AsyncConfigurer 接口,重写 getAsyncExecutor, 通过配置返回一个 taskExecutor 线程池
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(5);
        taskExecutor.setMaxPoolSize(10);
        taskExecutor.setQueueCapacity(25);
        taskExecutor.initialize();
        return taskExecutor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }
}

注意:上面的例子中,ThreadPoolTaskExecutor 并没有被 Spring 容器管理,可以在getAsyncExecutor()上添加 @Bean 注解让它变成 Spring 管理的 Bean。如果加入到 Spring容器,那么就不需要手动调用 executor.initialize() 做初始化了,因为在 Bean 初始化的时候会自动调用这个方法。

任务执行类

通过 @Async 注解表明该方法是个异步方法,如果注解在 class 上(类级别上),则表明该类所有的方法都是异步方法,而这里的方式是自动被注入使用 ThreadPoolTaskExecutor 作为 TaskExecutor,

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

@Service
public class AsyncTaskService {

    @Async // 通过 Async 注解表明该方法是一个异步的方法,如果注解在类级别,则表明该类下的所有方法都是 异步
    public void executeAsyncTask(Integer i){
        System.out.println("执行异步任务: "+i);
    }

    @Async
    public void executeAsyncTaskPlus(Integer i){
        System.out.println("执行异步任务+1: "+(i+1));
    }
}

任务运行类

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(TaskExecutorConfig.class);

        AsyncTaskService asyncTaskService = context.getBean(AsyncTaskService.class);

        for(int i =0 ;i<10;i++){
            asyncTaskService.executeAsyncTask(i);
            asyncTaskService.executeAsyncTaskPlus(i);
        }
        context.close();
    }
}

执行结果

打印出来的执行结果如下:

执行异步任务: 0
执行异步任务: 1
执行异步任务: 3
执行异步任务: 2
执行异步任务: 4
执行异步任务+1: 2
执行异步任务: 5
执行异步任务+1: 6
执行异步任务: 6
执行异步任务+1: 7
执行异步任务: 7
执行异步任务+1: 8
执行异步任务: 8
执行异步任务+1: 9
执行异步任务: 9
执行异步任务+1: 10
执行异步任务+1: 5
执行异步任务+1: 4
执行异步任务+1: 3
执行异步任务+1: 1
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Spring Boot提供了异步定时任务的支持。在Spring,我们可以使用@EnableScheduling注解来启用定时任务的功能,使用@Scheduled注解来标记一个方法为定时任务。同时,我们可以使用TaskExecutor和TaskScheduler接口来实现异步执行任务调度。 在绝大多数的Java应用,很多场景都是采用同步的方式进行交互。但是如果涉及到与第三方进行交互,可能会出现交互延迟的问题。为了解决这个问题,Spring在3版本之后内置了异步任务的支持,可以使用异步任务来处理这种情况。 在定时任务,有时候可能会遇到执行时长不确定的情况。但是如果需要固定间隔执行任务,可以使用@Scheduled注解的initialDelay和fixedDelay属性来实现。另外,如果需要控制同一时间只允许一个线程执行部分代码,可以使用AtomicBoolean来实现。具体的代码实现可以参考上述引用\[3\]的示例。 总结起来,Spring Boot提供了异步定时任务的支持,可以通过@EnableScheduling和@Scheduled注解来实现。同时,可以使用TaskExecutor和TaskScheduler接口来实现异步执行任务调度。如果需要固定间隔执行任务或控制同一时间只允许一个线程执行部分代码,可以使用@Scheduled注解的属性或AtomicBoolean来实现。 #### 引用[.reference_title] - *1* *2* [SpringBoot实现异步任务以及定时任务](https://blog.csdn.net/qq_41153943/article/details/124944826)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Springboot异步定时任务限制某方法同一时间只允许一个线程去运行](https://blog.csdn.net/New_Yao/article/details/126771642)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Wayfreem

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值