Spring boot异步任务线程池创建和配置

编程教程 > Java > Spring (5) 2025-09-15 12:55:52

Spring 注解默认方案

启用异步支持

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync  // 开启异步任务支持
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

定义异步方法

在需要异步执行的方法上使用 @Async 注解:

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncService {
    @Async  // 标记为异步方法
    public void doAsyncTask() {
        System.out.println("异步任务开始执行,线程名:" + Thread.currentThread().getName());
        try {
            Thread.sleep(3000); // 模拟耗时操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("异步任务执行完成");
    }
    @Async
    public CompletableFuture<String> doAsyncTaskWithResult() {
        System.out.println("带返回值的异步任务,线程名:" + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return CompletableFuture.completedFuture("任务完成");
    }
}

调用异步方法

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
    @Autowired
    private AsyncService asyncService;
    @GetMapping("/test-async")
    public String testAsync() {
        System.out.println("主线程开始:" + Thread.currentThread().getName());
        
        asyncService.doAsyncTask(); // 异步执行,不会阻塞
        
        System.out.println("主线程结束");
        return "请求已接收";
    }
}

代码全面配置方案(自定义线程池)

虽然 @EnableAsync 可以工作,但默认使用的是 SimpleAsyncTaskExecutor,不适合生产环境。推荐自定义线程池

1. 配置自定义 TaskExecutor

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
@EnableAsync
public class AsyncConfig {
    @Bean("taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);               // 核心线程数
        executor.setMaxPoolSize(10);               // 最大线程数
        executor.setQueueCapacity(100);            // 队列大小
        executor.setThreadNamePrefix("async-");    // 线程前缀名
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略
        executor.initialize(); // 初始化
        return executor;
    }
}

线程池@Bean名称注意事项:

默认线程池的创建逻辑

当 Spring 启动并处理 @EnableAsync 注解时,它会按照以下顺序查找或创建一个 Executor(即线程池):

  1. 查找名为 taskExecutorExecutor Bean
    Spring 会首先检查容器中是否存在一个名为 taskExecutorExecutor 类型的 Bean。如果存在,就使用它。
  2. 如果没有找到 taskExecutor,则使用默认的 SimpleAsyncTaskExecutor
    如果你没有定义 taskExecutor Bean,Spring 会自动创建一个默认的 SimpleAsyncTaskExecutor 实例来执行异步任务。

 

2. 在异步方法中指定使用的线程池

@Service
public class AsyncService {
    @Async("taskExecutor")  // 指定使用名为 taskExecutor 的线程池
    public void doAsyncWithCustomPool() {
        System.out.println("使用自定义线程池执行,线程名:" + Thread.currentThread().getName());
    }
}

3. (可选)配置异步任务异常处理器

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
@Configuration
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
    @Override
    public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
        System.err.println("异步方法抛出异常: " + method.getName());
        throwable.printStackTrace();
    }
}

然后在 AsyncConfig 中注册:

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    return new CustomAsyncExceptionHandler();
}

三、异步方法的返回值处理

  • void:最简单,不关心结果。
  • Future<T> / CompletableFuture<T>:可用于获取执行结果或处理回调。
@Async
public CompletableFuture<String> asyncProcess() {
    // 模拟处理
    return CompletableFuture.completedFuture("处理完成");
}
// 调用处
CompletableFuture<String> future = asyncService.asyncProcess();
future.thenAccept(result -> System.out.println("结果:" + result));

 

四、总结对比

方案 优点 缺点 适用场景
注解方案(@EnableAsync) 简单快捷,开箱即用 使用默认线程池,不适合高并发 快速原型、低并发场景
代码配置方案(自定义线程池) 可控性强,性能好,适合生产 需要额外配置 生产环境、高并发任务

 


评论
User Image
提示:请评论与当前内容相关的回复,广告、推广或无关内容将被删除。

相关文章
WebMvcConfigurer 中的 configureAsyncSupport 和 @EnableAsync 注解虽然都涉及“异步”,但它们服务于不同的异步
Spring 注解默认方案启用异步支持import org.springframework.boot.SpringApplication;import org.
概述前面讲解了Java普通项目如何创建线程池,使用的是java.util.concurrent.ThreadPoolExecutor jdk自带线程池对象。Sp
普通项目中使用Java线程池,创建线程池参考示例代码 ThreadPoolExecutor threadPoolExecutor = new ThreadPoo
在这篇文章中,我们将讨论有关使用异步任务执行程序功能在不同线程中执行任务的Spring boot异步执行支持。我们将看看在Spring项目中配置SimpleAsyncTaskExecutor,C...
spring boot 2.0 入门之单元测试多线程。spring boot 2.0 项目含多线程异步处理业务单元测试执行主线程结束不等待子线程结束。
Java基础多线程之主线程等待子线程结束,Java基础编程之多线程入门学习篇。主要讲解几种方法来实现Java多线程中主线程等待子线程结束的最快方式。
Spring作为一个IOC/DI容器,帮助我们管理了许许多多的“bean”。但其实,Spring并没有保证这些对象的线程安全,需要由开发者自己编写解决线程安全问题的代码。
java多线程编程_java多线程安全_java多线程实现安全锁CAS机制,CAS在java多线程中相当于数据库的乐观锁,synchronized相当于数据库的乐观锁。
Spring Boot定时任务阻塞解决方式一:修改定时任务的线程数量修改spring boot项目的application配置文件,将下面的配置修改为合适的值,默认1表示所有定时任务都是一个线程...
线程池创建 /** * 队列用线程 * @return */ @Bean(name = "queuePool") public Thread...
线程安全是像Java这样的语言/平台中的类的重要质量,我们经常在线程之间共享对象。由于缺乏线程安全性而导致的问题非常难以调试,因为它们零星且几乎不可能有意再现。你如何测试你的对象以确保它们是线程...
JavaScript是一个单线程应用程序,如果我们继续将该线程用于所有任务,用户将最终等待阻碍用户体验的其他任务。为了解决这个问题,我们进行了异步编程。Type
ThreadPoolExecutor 实现的拒绝策略有以下几种AbortPolicyDiscardPolicyDiscardOldestPolicyCaller