Spring 异步与线程池实战全解:失效原因、参数调优与 MQ 选型

很多后端同学在学习并发时都会经历三个阶段:

  1. @Async 用不起来
  2. 线程池参数不会调
  3. 不知道什么时候该用 MQ

如果你也卡在这三点,这篇文章就是为你准备的。

本文将从 实战工程视角,一文打通:

  • @Async 失效原因
  • 线程池参数调优
  • 线程池 vs MQ 选型思维

目标只有一句话:

不只是会用异步,而是理解"什么时候用、怎么用、用到什么程度"。

第一部分:@Async 为什么会失效?

这是 90% 初学者踩的坑。

1. 没有开启异步支持

错误:

java 复制代码
@SpringBootApplication
public class App {}

正确:

java 复制代码
@EnableAsync
@SpringBootApplication
public class App {}

2. 方法不是 public

Spring AOP 代理只能拦截 public 方法。

3. 同类内部调用

java 复制代码
this.sendEmail(); // 无效

必须通过 Spring 注入调用。

4. 默认线程池不可控

如果不自定义线程池:

  • 线程名混乱
  • 并发不可控
  • 容易打爆 CPU

5. 异常被吞掉

异步方法抛出的异常不会自动显示,需要日志或回调处理。

一句话总结:

@Async 不是魔法,本质是 AOP + 线程池。

第二部分:线程池参数怎么调?

线程池不是"越大越好"。

四个核心参数

参数 含义
coreSize 常驻线程
maxSize 最大线程
queueCapacity 排队容量
keepAlive 回收时间

通用经验值

CPU 密集型

java 复制代码
core = CPU 核心数 + 1

IO 密集型

java 复制代码
core = CPU × 2 ~ 3

拒绝策略选择

推荐:

java 复制代码
CallerRunsPolicy

含义:线程池满时让调用方执行,形成削峰。

线程池调优思维

不是凭感觉,而是:

  1. 压测
  2. 观察 CPU
  3. 观察队列堆积
  4. 微调参数

一句话总结:

线程池调优 = 压测 + 观察 + 调整。

第三部分:线程池 vs MQ 怎么选?

很多人会把两者混为一谈。

线程池的定位

适合:

  • 单服务内部并发
  • 写日志
  • 发邮件
  • 图片压缩

关键词:提速

MQ 的定位

适合:

  • 高并发注册
  • 秒杀
  • 订单系统
  • 削峰解耦

关键词:

注册场景拆解

同步主链路:

  • 参数校验
  • 唯一性校验
  • 写用户表

异步旁路:

  • 发短信
  • 发邮件
  • 发券
  • 写日志

一句话记忆:

线程池解决"快",MQ 解决"稳"。

最终总结

后端并发不是:

多开线程

而是:

合理调度资源 + 正确选型。

  1. @Async 解决"用"
  2. 线程池解决"稳"
  3. MQ 解决"系统级并发"

真正的后端工程能力,不在于 API 熟练度,

而在于:

知道什么时候用什么工具。

相关推荐
LaughingZhu14 小时前
智能体经典范式构建:ReAct、Plan-and-Solve 与 Reflection
前端·react.js·前端框架
H_HX12614 小时前
IDEA的下载和安装
java·intellij-idea·idea
AIGS00114 小时前
向量空间JBoltAI:本体语义如何跨越企业AI的语义鸿沟
java·大数据·人工智能·人工智能ai大模型应用
jsonbro14 小时前
手把手带你实现发布订阅模式
前端·vue.js·设计模式
一只猫的梦14 小时前
自动化模块 (Automation Module)
前端·chrome
r_oo_ki_e_14 小时前
Java 线程池
java·开发语言
日月云棠14 小时前
Spring 源码深度剖析:DispatcherServlet 的自动化注册机制
java·后端
熊猫钓鱼>_>14 小时前
Electron:当 Web 技术统治桌面
大数据·前端·javascript·人工智能·架构·electron·agent
德福危险14 小时前
从盲打xss到到模板注入:unix靶机渗透之Tempus_fugit4
前端·unix·xss
JavaGuide14 小时前
又一个画图 Skill 开源,再见手动画 draw.io!
前端·后端·github