ReentrantLock 源码分析

本文详细解析了AQS同步器中的AQS队列与ReentrantLock,探讨了ReentrantLock如何通过非公平锁和公平锁机制实现可重入独占锁,以及其acquire方法的工作原理。重点介绍了NonfairSync获取锁的过程和公平锁的区别。

AQS介绍

AQS是一个FIFO的双向队列。节点head和tail记录队首和队

Node结点:
shared用来标记该线程是获取共享资源时被阻塞挂起后放入AQS队列的
exclusive用来标记线程是获取独占资源时被挂起后放入AQS队列

waitStatus记录当前线程等待状态。如下:
1、cancelled线程取消
2、signal线程需要被唤醒
3、condition线程在条件队列里面等待
4、propagate释放共享资源需要通知其结点

Aqs内部类ConditionObject
操作state的方式分为独占方式和共享方式

ReentrantLock 概述

ReentrantLock 是基于AQS同步器的一种可重入的独占锁。同时只能有一个线程可以获取该锁

ReentrantLock 类图

在这里插入图片描述

Sycn继承了AQS同步器。他的子类NonfairSync和FairSync分别实现了非公平锁和公平锁。AQS的状态state状态值表示该锁的可重入次数。

ReentrantLock 源码

构造方法

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

    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

ReentrantLock 独占锁有两个构造方法,无参构造方法默认实现的是非公平锁(NonfairSync),有惨构造方法可以指定boolean类型,true表示公平锁(fairSync),反之为非公平锁

NonfairSync非公平锁获取锁

 final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

1、当第一个运行线程获取独占锁时,首先设置CAS状态sate为1,sate状态表示重入的次数。再者将锁的持有者设置为当前运行的线程。如果其他线程想获取该锁,只能在AQS队列里面挂起阻塞。等着锁的当前持有者释放。
2、当前线程已经持有改锁,只需要将sate状态重入的次数加1,

acquire方法获取锁

  */
        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()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

AbstractQueuedSynchronizer同步容器没有具体实现tryAcquire方法,由具体的子类实现,在独占锁ReentrantLock中,是由AbstractQueuedSynchronizer子类Sync实现的该方法。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值