java并发系列三(深入理解AQS和CAS)

本文详细介绍了AQS(AbstractQueuedSynchronizer)的核心概念,包括state变量、FIFO队列以及acquire和release方法的实现原理。AQS提供了独占和共享两种资源获取方式,并详细分析了acquire方法的执行流程,涉及tryAcquire、addWaiter、acquireQueued等关键函数。此外,文章还讨论了CAS(Compare And Swap)操作在Java并发中的应用,解释了乐观锁的概念及ABA问题,并给出了原子操作++i的CAS实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,AQS详解

参考博文https://www.cnblogs.com/waterystone/p/4920797.html
在这里插入图片描述
首先,AQS维护了一个共享变量state,和一个FIFO队列。state的访问方式有三种:
getState()
setState()
compareAndSetState()
AQS有独占和共享这两种资源共享方式。
自定义同步器只需要实现共享资源的state的获取与释放即可。需要实现如下方法:
isHeldExclusively():该线程是否正在独占资源
tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。
tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false。
tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回true,否则返回false。

源码详解!!!!!!
1,acquire方法
此方法是独占模式下线程获取state的顶层入口。源码如下

   public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

用到的函数如下
1,tryAcquire :尝试去获取state,如果成功则直接返回
2,addWaiter将该线程加入等待队列的尾部,并标记为独占模式
3,acquireQueued使线程在等待队列中获取资源,一直到获取到资源才返回。如果在整个等待过程中被中断过,则返回true,否则返回false。
4,selfInterrupt:进行自我中断

下面我们开始逐个方法分析
1,,tryAcquire 源码如下

  protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }

是不是有点蒙蔽,为啥就单单只是抛了个异常。AQS毕竟只是一个框架,具体的实现还要靠自定义的同步器自己去设计。
这里我们简要分析下lock中非公平锁的tryAcquire实现,源码如下

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;
        }

这段代码还是比较容易理解的。。。我就不多加赘述了。。。
2,addWaiter
源码如下

 private Node ad
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值