--- title: SpringBoot 线程与事件 date: 2026-06-02 --- # 一、基本概念   **进程**:进程是操作系统资源分配的最小单位,每个进程都有独立的内存空间(代码段、数据段、堆、栈),比如打开一个应用程序,就是一个进程。   **线程**:线程是 CPU 调度的最小单位,线程共享所属进程的内存空间。 比如一个HTTP请求就是一个线程。   **协程**:协程是 用户态的轻量级“线程”,由程序自己调度,不依赖操作系统,切换成本极低。   创建线程方法: ```java // 继承 Thread 不推荐 class MyThread extends Thread { @Override public void run() { System.out.println("线程运行中:" + Thread.currentThread().getName()); } } public class Test { public static void main(String[] args) { MyThread t = new MyThread(); t.start(); // ✅ 启动线程 } } // 实现 Runnable class MyRunnable implements Runnable { @Override public void run() { System.out.println("线程运行中:" + Thread.currentThread().getName()); } } public class Test2 { public static void main(String[] args) { Thread t = new Thread(new MyRunnable()); t.start(); } } // Lambda 写法 Thread t = new Thread(() -> { System.out.println("Hello Thread"); }); t.start(); // 线程池 ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, // 核心线程数 4, // 最大线程数 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy() ); ```   **SpringBoot线程池**: ```java // 1. 启动类加上 @EnableAsync 注解 @EnableAsync @SpringBootApplication public class Application { } // 2. 线程池配置 @Bean public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(20); executor.initialize(); return executor; } // 3. 调用方法上加上 @Async 注解 @Service public class OrderService { @Async public void createOrder() { System.out.println(Thread.currentThread().getName()); } } ``` # 二、案例   案例:电商秒杀系统。 - 资源竞争:多个用户抢同一件商品(多线程抢锁)。 - 异步解耦:扣减库存后,需要发短信、发优惠券(多线程并行)。 - 系统解耦:订单系统不应依赖短信系统(事件驱动)。 # 二、JDK原生线程通信 - synchronized:锁住库存,防止超卖。 - wait/notify:通知消息线程“库存已扣,可以发通知了”。 - Thread+ ExecutorService:实现多线程并行发通知。 ## 2.1 共享资源 ```java /** * 商品库存(共享资源) */ public class Stock { // 假设只有 1 件库存 public int count = 1; // 信号:是否有人下单成功 public volatile boolean ordered = false; } ``` ## 2.2 下单线程 ```java /** * 用户下单线程 */ public class OrderWorker extends Thread { private final Stock stock; public OrderWorker(Stock stock) { this.stock = stock; } @Override public void run() { // 1. 锁住库存,防止超卖 synchronized (stock) { if (stock.count > 0) { System.out.println(Thread.currentThread().getName() + " 抢到锁,准备扣库存"); stock.count--; stock.ordered = true; System.out.println("库存扣减成功,剩余:" + stock.count); stock.notifyAll(); // 通知消息线程 } else { System.out.println(Thread.currentThread().getName() + " 没抢到,库存不足"); } } } } ``` ## 2.3 消息分发线程 ```java /** * 消息分发线程 * 负责监听下单成功信号,并启动线程池发通知 */ public class MessageDispatcher extends Thread { private final Stock stock; private final ExecutorService pool; public MessageDispatcher(Stock stock, ExecutorService pool) { this.stock = stock; this.pool = pool; } @Override public void run() { synchronized (stock) { try { while (!stock.ordered) { System.out.println("消息线程:等待下单信号..."); stock.wait(); // 没下单就死等 } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("消息线程:收到下单成功信号,开始并行发通知!"); // 2. 并行执行通知任务 pool.execute(() -> System.out.println("线程池任务:发送短信")); pool.execute(() -> System.out.println("线程池任务:发放优惠券")); pool.execute(() -> System.out.println("线程池任务:更新用户积分")); } } } ``` ## 2.4 主程序 ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TraditionalDemo { public static void main(String[] args) { Stock stock = new Stock(); ExecutorService pool = Executors.newFixedThreadPool(3); // 消息线程先启动(等待) new MessageDispatcher(stock, pool).start(); // 模拟 3 个用户同时下单(竞争) new OrderWorker(stock).start(); new OrderWorker(stock).start(); new OrderWorker(stock).start(); } } ``` # 三、SpringBoot 异步方法 - @Transactional:保证库存扣减的事务性。 - @Async:将发短信、发券等耗时操作丢给线程池,立即释放 Tomcat 线程。 ## 3.1 配置线程池 ```java @Configuration @EnableAsync public class AsyncConfig { @Bean("orderExecutor") public Executor orderExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setThreadNamePrefix("Order-Async-"); executor.initialize(); return executor; } } ``` ## 3.2 订单服务 ```java @Service public class OrderService { @Autowired private StockService stockService; @Autowired private NotifyService notifyService; /** * 下单主流程 */ public void createOrder() { // 1. 扣库存(核心,同步) boolean success = stockService.decreaseStock(); if (!success) { throw new RuntimeException("库存不足"); } // 2. 异步通知(非核心,并行) notifyService.sendSms(); notifyService.sendCoupon(); } } ``` ## 3.3 通知服务 ```java @Service public class NotifyService { // 指定使用哪个线程池 @Async("orderExecutor") public void sendSms() { System.out.println(Thread.currentThread().getName() + " 发送短信"); } @Async("orderExecutor") public void sendCoupon() { System.out.println(Thread.currentThread().getName() + " 发放优惠券"); } } ``` # 四、SpringBoot 事件机制 - 事件(Event):下单成功这个“事实”。 - 发布者(Publisher):只负责发布事件,不关心后续。 - 监听者(Listener):谁关心下单成功,谁就干活(且可以异步)。 ## 4.1 定义事件 ```java public class OrderCreatedEvent { private final String orderId; public OrderCreatedEvent(String orderId) { this.orderId = orderId; } public String getOrderId() { return orderId; } } ``` ## 4.2 发布事件 ```java @Service public class OrderService { @Autowired private StockService stockService; @Autowired private ApplicationEventPublisher publisher; public void createOrder() { // 1. 扣库存 boolean success = stockService.decreaseStock(); if (success) { // 2. 发布事件(我不关心谁处理) publisher.publishEvent(new OrderCreatedEvent("ORDER_123")); } } } ``` ## 4.3 监听事件 ```java @Component public class OrderListener { // 监听下单事件,并异步执行 @EventListener @Async("orderExecutor") public void handleSendSms(OrderCreatedEvent event) { System.out.println(Thread.currentThread().getName() + " 监听到事件,发送短信"); } @EventListener @Async("orderExecutor") public void handleSendCoupon(OrderCreatedEvent event) { System.out.println(Thread.currentThread().getName() + " 监听到事件,发放优惠券"); } } ```