读写锁背景
锁为线程同步的实现之一。其本质是保证资源不会同时被多个线程修改,保证了并发时数据的安全性。
读写锁要点
读写操作分开加锁,可以在保证数据安全的同时,有效的提高读操作的并发性。但对于写操作居多的情况,对于提高效率帮助不大。尤其适用于读写分离时的从表。注意基于锁的同步会带来性能消耗。
读锁可以被认为是共享锁,写锁是排他锁。这正是JDK基于AQS实现读写锁的核心。
读写锁个人实现
读写锁实现可以参考:
此处参考Anwen:juejin.cn/post/684490…
此实现有如下问题:
1.全部方法使用synchronized关键字,本质在操作锁对象时序列化,效率较低
2.获取写锁时随机获取,导致写入时没有顺序,随机写入
3.所有获取锁的线程均会被阻塞,一旦某个写线程执行时间过长会导致读、写线程全部卡死。
4.拥有写锁的线程不支持直接获取读锁
读写锁JDK实现
JDK基于AQS实现读写锁。AQS可以实现各种锁特性,包括公平/非公平,可重入,共享/非共享等。AQS通过维护一个int类型的state值来完成各种锁状态的保存。
对于读写锁这种存在两个锁的情况,JDK通过将int值的前后16位拆分,分别保存读锁和写锁的状态。(此类中主要保存锁的数量,重入时加1。)
JDK中对该类的注释表明:
- 该类无法偏向于写/读,但可以实现基于时间的公平锁。
- 读锁、写锁均可设置为可重入
- 锁可降级,即可直接将线程的写锁降级为读锁
JDK实现时在内部分别维护了readLock和writeLock实例:
- readLock:主要依赖AQS的acquireShared、releaseShared
- writeLock: 主要依赖AQS的acquire、release方法
- 两个锁底层共用一个AQS
待完成。
读写锁应用场景
待完成。