Spring Boot 中多线程的基础使用

1. 核心机制

Spring Boot 通过 TaskExecutor@Async 注解支持多线程编程,结合线程池管理,有效提升应用性能。核心组件包括:

  • @EnableAsync:启用异步任务支持。

  • @Async:标记方法为异步执行。

  • ThreadPoolTaskExecutor :线程池实现,替代默认的 SimpleAsyncTaskExecutor


2. 基础配置与使用
(1) 启用异步支持

在启动类或配置类添加 @EnableAsync

java 复制代码
@SpringBootApplication
@EnableAsync
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}
(2) 定义线程池

通过 ThreadPoolTaskExecutor 配置线程池:

java 复制代码
@Configuration
public class AsyncConfig {

    @Bean("taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);          // 核心线程数
        executor.setMaxPoolSize(20);           // 最大线程数
        executor.setQueueCapacity(200);        // 队列容量
        executor.setThreadNamePrefix("Async-");// 线程名前缀
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略
        executor.initialize();
        return executor;
    }
}
(3) 使用 @Async 执行异步方法

在方法上添加 @Async 并指定线程池:

java 复制代码
@Service
public class MyService {

    @Async("taskExecutor")
    public void asyncTask() {
        // 异步执行的业务逻辑
        System.out.println("当前线程:" + Thread.currentThread().getName());
    }
}

3. 处理异步返回值
(1) 返回 CompletableFuture
java 复制代码
@Async("taskExecutor")
public CompletableFuture<String> asyncMethodWithReturn() {
    return CompletableFuture.completedFuture("任务完成");
}

// 调用示例
CompletableFuture<String> future = myService.asyncMethodWithReturn();
future.thenAccept(result -> System.out.println("结果: " + result));
(2) 返回 Future(旧版兼容)
java 复制代码
@Async("taskExecutor")
public Future<String> legacyAsyncMethod() {
    return new AsyncResult<>("任务完成");
}

// 调用示例
Future<String> future = myService.legacyAsyncMethod();
String result = future.get(); // 阻塞获取结果

4. 异常处理
(1) 自定义异常处理器

实现 AsyncUncaughtExceptionHandler

java 复制代码
@Configuration
public class AsyncExceptionConfig implements AsyncConfigurer {

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (ex, method, params) -> {
            System.err.println("异步方法异常: " + method.getName());
            ex.printStackTrace();
        };
    }
}
(2) 捕获特定异常

在异步方法内部使用 try-catch

java 复制代码
@Async("taskExecutor")
public void asyncTaskWithTryCatch() {
    try {
        // 可能抛出异常的代码
    } catch (Exception e) {
        // 处理异常
    }
}

5. 事务管理

异步方法默认不继承调用者的事务上下文,需显式配置:

java 复制代码
@Async("taskExecutor")
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void asyncTransactionalTask() {
    // 需要事务管理的数据库操作
}

6. 监控与调优
(1) 监控线程池状态

通过 ThreadPoolTaskExecutor 获取运行时指标:

java 复制代码
@Autowired
private ThreadPoolTaskExecutor taskExecutor;

public void monitorThreadPool() {
    System.out.println("活跃线程数: " + taskExecutor.getActiveCount());
    System.out.println("队列大小: " + taskExecutor.getThreadPoolExecutor().getQueue().size());
}
(2) 集成 Actuator

application.properties 中启用监控端点:

java 复制代码
management.endpoints.web.exposure.include=metrics
management.endpoint.metrics.enabled=true

访问 http://localhost:8080/actuator/metrics/executor.pool.size 查看线程池指标。


7. 高级场景
(1) 动态调整线程池参数

结合配置中心(如 Apollo、Nacos)动态刷新线程池配置:

java 复制代码
@RefreshScope
@Bean("taskExecutor")
public Executor taskExecutor(
    @Value("${thread.pool.core-size:10}") int coreSize,
    @Value("${thread.pool.max-size:20}") int maxSize
) {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(coreSize);
    executor.setMaxPoolSize(maxSize);
    // 其他配置
    return executor;
}
(2) 优雅关闭线程池

实现 DisposableBean 确保应用关闭时释放资源:

java 复制代码
@Bean("taskExecutor")
public Executor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    // ... 配置参数
    return executor;
}

@PreDestroy
public void destroy() {
    taskExecutor.shutdown();
    try {
        if (!taskExecutor.awaitTermination(60, TimeUnit.SECONDS)) {
            taskExecutor.shutdownNow();
        }
    } catch (InterruptedException e) {
        taskExecutor.shutdownNow();
        Thread.currentThread().interrupt();
    }
}

8. 典型应用场景
  • 批量数据处理:并行处理 CSV/Excel 导入导出。

  • 异步通知:发送短信、邮件、消息队列。

  • 耗时操作:生成报表、调用外部 API。

  • 高并发请求:Web 请求的异步响应(如 Spring WebFlux 结合)。


总结

通过 @Async 和线程池配置,Spring Boot 可高效实现多线程编程。关键步骤包括:

  1. 启用异步支持@EnableAsync

  2. 定制线程池 :配置 ThreadPoolTaskExecutor

  3. 异常与事务管理:处理异步任务中的错误和事务边界。

  4. 监控与调优:利用 Actuator 和动态配置优化性能。

最佳实践:避免在异步方法中处理大量同步阻塞操作,合理设置线程池参数,结合监控工具持续优化。

相关推荐
Boilermaker199211 分钟前
【Java EE】Mybatis-Plus
java·开发语言·java-ee
千鼎数字孪生-可视化12 分钟前
Web技术栈重塑HMI开发:HTML5+WebGL的轻量化实践路径
前端·html5·webgl
凌辰揽月13 分钟前
7月10号总结 (1)
前端·css·css3
xdscode32 分钟前
SpringBoot ThreadLocal 全局动态变量设置
java·spring boot·threadlocal
lifallen35 分钟前
Paimon 原子提交实现
java·大数据·数据结构·数据库·后端·算法
天天扭码36 分钟前
很全面的前端面试——CSS篇(上)
前端·css·面试
EndingCoder39 分钟前
搜索算法在前端的实践
前端·算法·性能优化·状态模式·搜索算法
丶小鱼丶43 分钟前
链表算法之【合并两个有序链表】
java·算法·链表
sunbyte43 分钟前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | DoubleVerticalSlider(双垂直滑块)
前端·javascript·css·vue.js·vue
Favor_Yang1 小时前
SQL Server通过存储过程实现HTML页面生成
前端·信息可视化·sqlserver·存储过程