江湖险恶:ReadWriteLock 与 ReentrantLock 的爱恨情仇

167 阅读3分钟

话说在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%)
  • 例如:缓存、配置、排行榜、商品库存查询

【四】相爱相杀的区别

特点ReentrantLockReadWriteLock
是否可重入
读写分离
并发性能中等读高写低
公平性支持支持
可中断支持支持
超时机制支持支持
条件队列支持不支持

核心差别一句话总结:
👉 ReentrantLock 是一把锁控制一切;
👉 ReadWriteLock 是两把锁分工合作。


【五】锁的 static —— 全局锁定还是对象锁?

很多人问:

ReadWriteLock 加上 static,是不是和 ReentrantLock 加上 static 一样,属于全局锁定?

答案是:是的!

✅ static 决定了锁的“归属”

static 加 or 不加锁定范围影响
ReentrantLock不加 static对象级别每个实例有自己的锁
ReentrantLock加 static类级别所有实例共享同一把锁
ReadWriteLock不加 static对象级别每个实例独立的读写锁
ReadWriteLock加 static类级别所有实例共享同一套读写锁

🏰 锁定的不是线程,而是资源!

  • static 锁 = 类锁,全局唯一
  • 非 static 锁 = 对象锁,各自为政

线程只是「拿钥匙开门」的人,而不是「门锁」的主人。

🚀 小结:

static 锁 = 全局锁;非 static 锁 = 当前对象锁。
锁定的是资源,不是线程


【六】武林秘籍:如何选择?

  1. 读多写少 → ReadWriteLock

    比如:新闻网站、商品信息查询、配置管理系统

  2. 写多读多或操作复杂 → ReentrantLock

    比如:账户转账、订单支付、库存扣减

  3. 简单粗暴,不想动脑 → synchronized(是的,这位老大哥还在)


【七】江湖小贴士(诙谐版)

  • 🔑 读写锁就像公共图书馆:大家可以一起看书(读),但有人在装修(写)时,只能等着。
  • 🏰 ReentrantLock就像古代宫门:皇帝批奏折(写)时,谁都不能进,连太监传话(读)也不行。
  • 🐢 千万别用读写锁来保护修改频繁的数据,那是画蛇添足
  • 🐇 反过来,读操作特别多时,用 ReentrantLock 是杀鸡用牛刀

【八】结语

江湖险恶,选锁有道。
选对了锁,代码顺畅如行云流水;选错了锁,线程争抢、性能低下、死锁横生。

愿你在并发的世界里,
锁得住繁花,开得起春风。