ReentrantReadWriteLock 读写锁获取与释放源码解析

本文详细介绍了ReentrantReadWriteLock的读写锁获取与释放过程,包括构造函数、同步状态、WriteLock和ReadLock的获取与释放逻辑。通过分析源码,揭示了其内部如何维护读写状态以及锁的重入和释放机制。
摘要由CSDN通过智能技术生成

ReentrantReadWriteLock 读写锁

构造函数

与ReentrantLock相类似, 其自定义同步器Sync分为公平锁FairSync与非公平锁NonfairSync的两种.

默认为NonfairSync

public ReentrantReadWriteLock() {
        this(false);
    }

public ReentrantReadWriteLock(boolean var1) {
    this.sync = (ReentrantReadWriteLock.Sync)(var1?new ReentrantReadWriteLock.FairSync():new ReentrantReadWriteLock.NonfairSync());
    this.readerLock = new ReentrantReadWriteLock.ReadLock(this);
    this.writerLock = new ReentrantReadWriteLock.WriteLock(this);
}

同步状态

同步状态表示锁被一个线程重复获取的次数. 而ReentrantReadWriteLock的自定义同步器Sync需要在同步状态(一个整型变量)上维护多个读线程和一个写线程的状态. 读写锁通过将该整型变量”按位切割使用”, 切分为两个部分, 高16位表示读, 低16位表示写
image

//ReentrantReadWriteLock.java: ReentrantReadWriteLock.Sync 
// 获取写同步锁状态
static int exclusiveCount(int var0) {
    return var0 & '\uffff';
}

// 获取读同步锁状态
static int sharedCount(int var0) {
            return var0 >>> 16;
        }

WriteLock 写锁

获取

获取锁的全过程: ReentrantReadWriteLock.WriteLock.lock() –> this.sync.acquire(1) (即 AbstractQueueSynchronizer.acquire(int var1)) –> ReentrantReadWriteLock.WriteLock.tryAcquire(1)

  • 获取写锁成功: ReentrantReadWriteLock.WriteLock.tryAcquire(1)返回true, AbstractQueueSynchronizer.acquireQueued()返回true
  • 获取写锁阻塞: ReentrantReadWriteLock.WriteLock.tryAcquire(1)返回false, AbstractQueueSynchronizer.acquireQueued()阻塞, 自旋锁
// ReentrantReadWriteLock.java: ReentrantReadWriteLock.WriteLock
public void lock() {
            this.sync.acquire(1);
        }

this.sync为ReentrantReadWriteLock自定义同步器Sync的实例(也是ReentrantReadWriteLock实例的成员变量), 是AbstractQueueSynchronizer的子类.

// AbstractQueueSynchronizer.java AbstractQueueSynchronizer
public final void acquire(int var1) {
        if(!this.tryAcquire(var1) && this.acquireQueued(this.addWaiter(AbstractQueuedSynchronizer.Node.EXCLUSIVE), var1)) { 
            selfInterrupt();
        }

    }

由于this.sync重写了父类的tryAcquire()等方法, 所以this.tryAcquire会调用重写后的方法

// ReentrantReadWriteLock.java: ReentrantReadWriteLock.WriteLock
protected final boolean tryAcquire(int var1) {
    Thread var2 = Thread.currentThread();
    int var3 = this.getState();
    int var4 = exclusiveCount(var3);  // 获取写状态
    if(var3 != 0) { 
        // 支持重进入
        if(var4 != 0 && var2 == this.getExcl
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值