1. 项目概述
最近在技术社区看到一个很有意思的线程同步教学案例 - 通过"抢奶茶"的场景来解释synchronized、ReentrantLock和wait/notify机制。作为一个常年和并发编程打交道的开发者,我觉得这个类比非常贴切,决定用图解+代码的方式,完整还原这个教学场景。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心场景设定
2.1 奶茶店模型
想象一家网红奶茶店,有三个关键角色:
- 奶茶制作台(共享资源)
- 多位顾客(多线程)
- 一位店员(协调线程)
顾客们会同时来点单,但制作台一次只能做一杯奶茶。这就产生了典型的线程竞争问题。
2.2 问题抽象
用技术术语描述:
- 制作台 = 共享资源
- 顾客 = 竞争线程
- 制作过程 = 临界区代码
- 店员 = 线程调度器
3. 同步方案实现
3.1 synchronized方案
java复制public class MilkTeaShop {
private final Object lock = new Object();
public void makeTea(String customer) {
synchronized(lock) {
System.out.println(customer + "开始制作");
// 模拟制作耗时
try { Thread.sleep(1000); }
catch (InterruptedException e) {}
System.out.println(customer + "的奶茶完成");
}
}
}
关键点:
- 使用对象内置锁
- 自动获取/释放锁
- 简单但不够灵活
3.2 ReentrantLock方案
java复制public class MilkTeaShop {
private final ReentrantLock lock = new ReentrantLock();
public void makeTea(String customer) {
lock.lock();
try {
System.out.println(customer + "开始制作");
Thread.sleep(1000);
System.out.println(customer + "的奶茶完成");
} finally {
lock.unlock();
}
}
}
优势:
- 可中断的锁获取
- 公平锁选项
- 尝试获取锁
- 更细粒度的控制
3.3 wait/notify方案
java复制public class MilkTeaShop {
private boolean isMaking = false;
public synchronized void makeTea(String customer)
throws InterruptedException {
while(isMaking) {
wait();
}
isMaking = true;
System.out.println(customer + "开始制作");
Thread.sleep(1000);
System.out.println(customer + "的奶茶完成");
isMaking = false;
notifyAll();
}
}
特点:
- 条件等待
- 线程间通信
- 必须配合synchronized使用
- 更复杂的协调逻辑
4. 对比分析
| 特性 | synchronized | ReentrantLock | wait/notify |
|---|---|---|---|
| 锁获取方式 | 自动 | 手动 | 条件等待 |
| 可中断 | 否 | 是 | 是 |
| 公平锁 | 否 | 可选 | 否 |
| 超时尝试 | 否 | 是 | 否 |
| 多条件变量 | 否 | 是 | 是 |
| 代码复杂度 | 低 | 中 | 高 |
5. 实际应用建议
- 简单场景优先用synchronized
- 需要高级功能时用ReentrantLock
- 线程间需要协调通信时用wait/notify
- 注意避免死锁和活锁
- 考虑使用更高层次的并发工具类
6. 常见问题排查
- 死锁:检查锁的获取顺序
- 活锁:检查条件判断逻辑
- 线程饥饿:考虑公平锁
- 虚假唤醒:总是用while检查条件
- 性能问题:减少临界区范围
提示:在IDE调试时,可以给线程设置有意义的名字,方便问题追踪。
7. 扩展思考
这个奶茶店模型还可以扩展:
- 多制作台(多资源管理)
- VIP通道(线程优先级)
- 外卖订单(异步处理)
- 原料库存(资源限制)
通过这样生活化的类比,复杂的线程同步概念变得直观易懂。我在实际教学中发现,这种案例驱动的讲解方式,能让新手更快掌握并发编程的核心要点。
