Java读写锁

123 阅读2分钟

读写锁背景

锁为线程同步的实现之一。其本质是保证资源不会同时被多个线程修改,保证了并发时数据的安全性。

读写锁要点

读写操作分开加锁,可以在保证数据安全的同时,有效的提高读操作的并发性。但对于写操作居多的情况,对于提高效率帮助不大。尤其适用于读写分离时的从表。注意基于锁的同步会带来性能消耗。

读锁可以被认为是共享锁,写锁是排他锁。这正是JDK基于AQS实现读写锁的核心。

读写锁个人实现

读写锁实现可以参考:

此处参考Anwenjuejin.cn/post/684490…

此实现有如下问题:

1.全部方法使用synchronized关键字,本质在操作锁对象时序列化,效率较低

2.获取写锁时随机获取,导致写入时没有顺序,随机写入

3.所有获取锁的线程均会被阻塞,一旦某个写线程执行时间过长会导致读、写线程全部卡死。

4.拥有写锁的线程不支持直接获取读锁

读写锁JDK实现

JDK基于AQS实现读写锁。AQS可以实现各种锁特性,包括公平/非公平,可重入,共享/非共享等。AQS通过维护一个int类型的state值来完成各种锁状态的保存。

对于读写锁这种存在两个锁的情况,JDK通过将int值的前后16位拆分,分别保存读锁和写锁的状态。(此类中主要保存锁的数量,重入时加1。)

JDK中对该类的注释表明:

  1. 该类无法偏向于写/读,但可以实现基于时间的公平锁。
  2. 读锁、写锁均可设置为可重入
  3. 锁可降级,即可直接将线程的写锁降级为读锁

JDK实现时在内部分别维护了readLock和writeLock实例:

  • readLock:主要依赖AQS的acquireShared、releaseShared  
  • writeLock: 主要依赖AQS的acquire、release方法
  • 两个锁底层共用一个AQS

待完成。

读写锁应用场景

待完成。