AQS子类的tryAcquire和tryRelease的实现

本文深入探讨了AQS(AbstractQueuedSynchronizer)子类如何实现tryAcquire和tryRelease方法,以及它们在ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch和ThreadPoolExecutor等工具类中的应用。AQS的核心在于state状态值的管理,子类通过覆写try*()方法来决定锁的获取和释放。独占锁和共享锁的实现方式有所不同,tryAcquire和tryRelease是关键。文章还详细分析了不同子类的具体实现策略,揭示了JUC的设计思想。
摘要由CSDN通过智能技术生成

为什么要单独将这部分抽出来总结?

纵观JUC下基于AQS实现的工具类,其实现思想都很统一:

  1. state代表状态值
  2. 通过try*()方法尝试单次更改state,根据state当前情况决定是否进入do*()中
  3. 一旦进入了do*()中,就代表了可能加入同步/等待队列中进行阻塞等待
  4. 而当线程从阻塞苏醒后,又会通过try*()方法尝试单次更改state,并根据state当前情况决定是否设置自身为新的头节点或阻塞与否

因此锁的获取能否,关键还是看子类复写的try*()方法,AQS自身提供的其他的方法都是对获取成功或失败的辅助工作
本文单独将try*()提出来,下文将do*()提出来,从而更好的理解JUC的设计思想

暴露方法

// 尝试获取 独占锁
protected boolean tryAcquire(int arg) {
   
        throw new UnsupportedOperationException();
}
// 尝试释放 独占锁
protected boolean tryRelease(int arg) {
   
        throw new UnsupportedOperationException();
}
//尝试获取 共享锁
protected int tryAcquireShared(int arg) {
   
        throw new UnsupportedOperationException();
}
//尝试释放 共享锁
protected boolean tryReleaseShared(int arg) {
   
        throw new UnsupportedOperationException();
}
//判断是否时当前线程在持有锁
protected boolean isHeldExclusively() {
   
        throw new UnsupportedOperationException();
}

以上五个方法时AQS向外暴露的方法,子类只需要覆盖这几个方法即可注意着五个方法并不是抽象方法,因此子类并不是必须全部覆盖这些方法。JUC中实现这些方法的子类有
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
独占锁是仅能有一个线程持有锁,而共享锁是可以同时多个线程持有锁的,因此独占锁和共享锁的实现方式分开实现
除了以上的四种try*()方法外,AQS自身实现了诸多的如acquiredoAcquire()等方法,他们之间的区别在于try*()方法代表一次尝试性的获取锁操作,如果获取到了就拿到了锁,否则直接返回。而AQS自身实现的acquiredoAcquire()等方法如果获取不到锁会能够进入同步/等待队列中阻塞等待进行锁的争夺,直到拿到了锁返回。对于共享锁,try*()也会进行自旋获取,因为共享锁可以被多个线程持有
在这里插入图片描述
AQS通过一个private volatile int state;来表示锁的状态,当state=0时代表无锁,>0代表有锁,>1代表重入次数
AQS从AOS继承了private transient Thread exclusiveOwnerThread;用来记录当前持有独占锁的线程

下面介绍不同子类的try*()方法实现

不同的子类实现

ReentrantLock

ReentrantLock实现了独占锁的尝试获取和尝试释放方法,因此我们从这里可以看出ReentrantLock是一种独占锁

  1. 非公平锁:线程获取锁不会排队,谁拿到算谁的
protected final boolean tryAcquire(int acquires){
   
 final Thread current = Thread.currentThread();
            int c = getState();
            // state==0代表当前没有锁,可以进行获取
            if (c == 0) {
   
            //CAS设置state为acquires,成功后标记exclusiveOwnerThread为当前线程
                if (compareAndSetState(0, acquires)) {
   
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            //代表重入,满足条件直接进行state的增加,因为持有锁,所以不需要CAS
            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;
}

// 调用该方法表明该线程是持有锁的,因此不需要CAS操作
protected final boolean tryRelease(int releases){
   
 			int c = getState(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值