readwritelock适用于读远多于写的场景,需轻量用读锁、精准用写锁、严格配对释放;写占比超20%时应改用reentrantlock或synchronized。

ReadWriteLock 不是给代码“加把锁就变快”的魔法,而是通过读写操作的语义分离,在读远多于写的场景下释放并发潜力。关键在用对方式——读锁要轻、写锁要准、释放要稳。
读锁必须轻量,只做真正“读状态”的事
读锁共享的优势,只有在它持有时间极短时才能体现。一旦拖长,写线程就会排队等待,反而造成“写饥饿”。
- ✅ 推荐放在锁内的操作:查 HashMap、取 volatile 字段、访问 final 字段、读缓存值
- ❌ 必须移出锁外的操作:远程调用(RPC/HTTP)、数据库查询、JSON 序列化、日志打印、大对象拷贝、耗时计算
- ⚠️ 特别注意:读锁内不能有副作用。比如一边读一边往日志队列塞消息,看似“只是读”,实则引入了写行为和外部依赖
写锁获取要快,但更新要严谨
写锁本身不慢,慢的是它必须等所有当前读锁全部释放后才能拿到。所以写操作前后的逻辑设计直接影响整体响应。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 写前校验一致性:比如先 check 状态再 update,或配合版本号/CAS 避免覆盖
- 写后可降级为读锁:若写完立刻要读新值,可在持有写锁时先获取读锁,再释放写锁(锁降级),避免重复加锁和竞态
- 绝对禁止读锁升级:在已持读锁时调 writeLock().lock() 会永久阻塞,JVM 不支持该行为
锁必须配对释放,且只能本线程 unlock
ReadWriteLock 不做类型检查,readLock().lock() 必须由同一线程调用 readLock().unlock(),writeLock 同理。错配会导致锁泄漏,后续所有线程卡死。
- 务必用 try-finally 包裹,不能依赖作用域自动释放
- 不要跨线程传递锁对象或委托解锁
- 非公平模式(默认)更推荐:吞吐高 15%~30%,除非监控发现写锁平均等待超 50ms,否则无需启用公平模式
写操作占比超阈值,就要换方案
ReadWriteLock 的 CAS 和内存屏障开销比 synchronized 更高。当写操作频繁时,协调成本反超收益。
- 写占比 ≤ 10%~15%:适合 ReadWriteLock
- 写占比 15%~20%:需压测对比,观察写锁等待时间和 GC 压力
- 写占比 > 20%:应回退到 ReentrantLock 或 synchronized,更稳定高效
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










