话说在Java的江湖上,有两大门派闻名遐迩,一个叫ReentrantLock(可重入锁) ,一个叫ReadWriteLock(读写锁) 。
江湖人称:一个讲究「一夫当关,万夫莫开」,一个讲究「以和为贵,能读就别写」。
今天我们就来揭开它们的面纱,聊聊它们的区别、用法、场景,顺便插科打诨,轻松一下。
【一】人物介绍
| 锁派 | 简介 | 主要技能 | 适用场景 |
|---|---|---|---|
| ReentrantLock | 可重入锁,一把锁走天下 | 支持公平锁/非公平锁、可中断、超时、Condition | 读多写多、竞争激烈 |
| ReadWriteLock | 读写分离,善于协调 | 读多写少,提升并发性 | 典型读多写少场景 |
【二】ReentrantLock:霸道总裁,万事亲力亲为
ReentrantLock 是个「霸道总裁」,不分青红皂白,谁进来都要排队。就算只是读个数,也得等别人写完。效率?它不太关心。
ReentrantLock lock = new ReentrantLock();
public void doSomething() {
lock.lock();
try {
System.out.println("正在加锁执行任务...");
} finally {
lock.unlock();
}
}
适用场景:
- 写操作多,读操作也不少
- 操作之间没有明确的“读写”分界
- 需要公平锁、可中断、超时等待等高级玩法
【三】ReadWriteLock:温文尔雅,儒雅随和
ReadWriteLock 是个「温柔派」,专注于读写分离。
- 读:大家一起读,井然有序,互不干扰
- 写:写的时候,谁都别插队
ReadWriteLock rwLock = new ReentrantReadWriteLock();
Lock readLock = rwLock.readLock();
Lock writeLock = rwLock.writeLock();
public void read() {
readLock.lock();
try {
System.out.println("读锁开启:大家一起看");
} finally {
readLock.unlock();
}
}
public void write() {
writeLock.lock();
try {
System.out.println("写锁开启:独家访问,禁止围观");
} finally {
writeLock.unlock();
}
}
适用场景:
- 读远多于写(典型比例:读95% 写5%)
- 例如:缓存、配置、排行榜、商品库存查询
【四】相爱相杀的区别
| 特点 | ReentrantLock | ReadWriteLock |
|---|---|---|
| 是否可重入 | 是 | 是 |
| 读写分离 | 否 | 是 |
| 并发性能 | 中等 | 读高写低 |
| 公平性 | 支持 | 支持 |
| 可中断 | 支持 | 支持 |
| 超时机制 | 支持 | 支持 |
| 条件队列 | 支持 | 不支持 |
核心差别一句话总结:
👉 ReentrantLock 是一把锁控制一切;
👉 ReadWriteLock 是两把锁分工合作。
【五】锁的 static —— 全局锁定还是对象锁?
很多人问:
ReadWriteLock 加上 static,是不是和 ReentrantLock 加上 static 一样,属于全局锁定?
答案是:是的!
✅ static 决定了锁的“归属”
| 锁 | static 加 or 不加 | 锁定范围 | 影响 |
|---|---|---|---|
ReentrantLock | 不加 static | 对象级别 | 每个实例有自己的锁 |
ReentrantLock | 加 static | 类级别 | 所有实例共享同一把锁 |
ReadWriteLock | 不加 static | 对象级别 | 每个实例独立的读写锁 |
ReadWriteLock | 加 static | 类级别 | 所有实例共享同一套读写锁 |
🏰 锁定的不是线程,而是资源!
- static 锁 = 类锁,全局唯一
- 非 static 锁 = 对象锁,各自为政
线程只是「拿钥匙开门」的人,而不是「门锁」的主人。
🚀 小结:
static 锁 = 全局锁;非 static 锁 = 当前对象锁。
锁定的是资源,不是线程!
【六】武林秘籍:如何选择?
-
读多写少 → ReadWriteLock
比如:新闻网站、商品信息查询、配置管理系统
-
写多读多或操作复杂 → ReentrantLock
比如:账户转账、订单支付、库存扣减
-
简单粗暴,不想动脑 → synchronized(是的,这位老大哥还在)
【七】江湖小贴士(诙谐版)
- 🔑 读写锁就像公共图书馆:大家可以一起看书(读),但有人在装修(写)时,只能等着。
- 🏰 ReentrantLock就像古代宫门:皇帝批奏折(写)时,谁都不能进,连太监传话(读)也不行。
- 🐢 千万别用读写锁来保护修改频繁的数据,那是画蛇添足。
- 🐇 反过来,读操作特别多时,用 ReentrantLock 是杀鸡用牛刀。
【八】结语
江湖险恶,选锁有道。
选对了锁,代码顺畅如行云流水;选错了锁,线程争抢、性能低下、死锁横生。
愿你在并发的世界里,
锁得住繁花,开得起春风。