💬 本文由 Claude 对话整理而来,含交互式动画演示。查看完整对话 ↗
一、按锁的粒度分
数据库锁:表锁(锁整张表)→ 页锁(锁一个数据页)→ 行锁(锁单行记录,InnoDB 默认)。粒度越细并发越高,但开销越大。
应用层锁:全局锁(如 Python GIL、MySQL FTWRL)和对象级锁(锁某个具体资源实例)。
二、按锁的模式/兼容性分
- 共享锁(S Lock / 读锁):多个事务可同时持有,只读不写
- 排他锁(X Lock / 写锁):独占资源,读写都阻塞其他事务
- 意向锁(IS / IX):表级与行级锁之间的协调信号
- 更新锁(U Lock):SQL Server 特有,先读后写场景避免死锁
三、按锁的实现策略分
悲观锁:假设冲突一定发生,先加锁再操作。典型:SELECT ... FOR UPDATE、synchronized、Mutex。
乐观锁:假设冲突很少,操作时不加锁,提交时用版本号/CAS 检查。典型:数据库 version 字段、AtomicInteger、Redis WATCH。
四、按锁的行为特性分
- 可重入锁(Reentrant Lock):同一线程可多次获取同一把锁
- 公平锁 vs 非公平锁:公平锁按序排队;非公平锁允许插队,吞吐更高
- 自旋锁(Spinlock):获取不到锁时原地循环重试,适合临界区极短场景
- 读写锁(RWLock):读读并发、读写互斥、写写互斥,适合读多写少
五、分布式环境下的锁
| 方案 | 实现方式 | 优缺点 |
|---|---|---|
| Redis 分布式锁 | SET key NX EX / Redlock | 高效,注意时钟漂移和主从切换 |
| ZooKeeper | 临时有序节点 | 强一致,性能较低 |
| etcd | Raft 共识 + Lease | Go 生态常用 |
| 数据库锁 | 唯一索引 / FOR UPDATE | 简单但高并发不推荐 |
六、MySQL InnoDB 专有锁
- 间隙锁(Gap Lock):锁索引记录间的间隙,防幻读
- 临键锁(Next-Key Lock):行锁 + 间隙锁组合,RR 隔离级别默认使用
- 插入意向锁:同一间隙不同位置插入互不阻塞
- 元数据锁(MDL):DDL 与 DML 互斥
- 自增锁:保证 AUTO_INCREMENT 连续分配
七、编程语言层同步原语速查
| 原语 | 说明 |
|---|---|
| Mutex / Lock | 最基本互斥锁 |
| RWMutex | 读写锁 |
| Semaphore | 控制并发数量 |
| Condition Variable | 线程间通知等待 |
| CountDownLatch | 等待 N 个任务完成 |
| CyclicBarrier | N 个线程互等到齐 |
| StampedLock | Java 8+ 乐观读锁 |
八、选型速查
- 单机短临界区 → 自旋锁
- 单机读多写少 → 读写锁
- 单机通用 → Mutex / ReentrantLock + 条件变量
- 数据库事务 → 行锁 + 乐观锁版本号
- 分布式 → Redis / ZooKeeper / etcd 分布式锁
