ReentrantLock可重入锁的实现原理


首先先介绍Lock接口,然后通过分析ReentrantLock的lock方法和unlock方法,来解释ReentrantLock的内部原理.

1. Lock接口

Lock接口,是对控制并发的工具的抽象。它比使用synchronized关键词更灵活,并且能够支持条件变量。

  • 它是一种控制并发的工具,一般来说,它控制对某种共享资源的独占。也就是说,同一时间内只有一个线程可以获取这个锁并占用资源。其他线程想要获取锁,必须等待这个线程释放锁。在Java实现中的ReentrantLock就是这样的锁。
  • 另外一种锁,它可以允许多个线程读取资源,但是只能允许一个线程写入资源,ReadWriteLock就是这样一种特殊的锁,简称读写锁。

lock接口常见的几个方法

  • lock():获取锁,如果锁无法获取,那么当前的线程就变为不可被调度,直到锁被获取到,当前线程不可被中断
  • unlock 释放当前线程占用的锁
  • lockInterruptibly :获取锁,除非当前线程被中断。
  • tryLock:如果调用的时候能够获取锁,那么就获取锁并且返回true,如果当前的锁无法获取到,那么这个方法会立刻返回false
  • newCondition:返回一个与当前的锁关联的条件变量。在使用这个条件变量之前,当前线程必须占用锁。调用Condition的await方法,会在等待之前原子地释放锁,并在等待被唤醒后原子的获取锁

2. 公平锁和非公平锁的实现

2.1 公平锁

公平锁对应的逻辑是 ReentrantLock 内部静态类 FairSync

static final class FairSync extends Sync {
   
    final void lock() {
   
        acquire(1);
    }
    // AbstractQueuedSynchronizer.acquire(int arg)
    public final void acquire(int arg) {
   
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }
    protected final boolean tryAcquire(int acquires) {
   
        final Thread current = Thread.currentThread();
        int c = getState();
        if (c == 0) {
   
            // 1. 和非公平锁相比,这里多了一个判断:是否有线程在等待
            if (!hasQueuedPredecessors() &&
                compareAndSetState(0, acquires)) {
   
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        else if (current == getExclusiveOwnerThread()) {
   
            int nextc = c + acquires;<
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值