ReentrantLock是怎么实现可重入的

ReentrantLock 可重入原理

从构造函数可以看到,ReentrantLock 默认为非公平锁实现,内部初始化了一个非公平同步器

public ReentrantLock() {
   sync = new NonfairSync();
}

其内部的非公平同步器NonfairSync继承于抽象内部类Sync,Sync又继承自AbstractQueuedSynchronizer

ReentrantLock 可重入的原理依赖于NonfairSync继承的抽象内部类Sync中的两个方法,通过state计数的增加减少来实现可重入

nonfairTryAcquire()

这个方法在尝试获取锁时,如果锁已被占有,就用当前尝试获取锁的线程与当前占有锁的线程进行比较,如果是同一线程,就说明是发生了重入,此时给state计数加1,并返回true说明锁重入成功

tryRelease()

这个方法在尝试释放锁时,只有state计数成功减少到了0,才真正的释放锁并把占用锁的线程置为null

static final class NonfairSync extends Sync {
}
​
abstract static class Sync extends AbstractQueuedSynchronizer {
    
    final boolean nonfairTryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        if (c == 0) {
            if (compareAndSetState(0, acquires)) {
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        // 如果已经获得了锁, 线程还是当前线程, 表示发生了锁重入
        else if (current == getExclusiveOwnerThread()) {
            // state++
            int nextc = c + acquires;
            if (nextc < 0) // overflow
                throw new Error("Maximum lock count exceeded");
            setState(nextc);
            return true;
        }
        return false;
    }
    
    protected final boolean tryRelease(int releases) {
        // state-- 
        int c = getState() - releases;
        if (Thread.currentThread() != getExclusiveOwnerThread())
            throw new IllegalMonitorStateException();
        boolean free = false;
        // 支持锁重入, 只有 state 减为 0, 才释放成功
        if (c == 0) {
            free = true;
            setExclusiveOwnerThread(null);
        }
        setState(c);
        return free;
    }
}

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值