AQS详解3-源码解读(上)

本文深入探讨AQS(AbstractQueuedSynchronizer)的非公平锁实现,通过源码分析加锁和解锁过程。以ReentrantLock为例,详细阐述线程如何通过CAS操作、自旋及LockSupport实现等待唤醒。文章通过业务场景模拟,解释线程在加锁失败后如何进入等待队列并被阻塞,同时为后续解锁过程埋下伏笔。

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

此篇文章不再AQS的基础理论和体系,会直接从AQS的源码和原理进行剖析,如果还不了解AQS的可以先看一下前两篇文章
AQS详解1-理论介绍
AQS详解2-体系架构介绍

一.先说原理结论.

在之前我们已经总结到AQS=state+CLH双端队列,利用CAS,自旋,以及LockSupport实现了对线程的等待唤醒操作.
这里以ReentrantLock以切入点,研究非公平锁的具体过程.
那究竟是怎样实现的呢?这里先说实现步骤.
1.加锁过程.
在这里插入图片描述

2.解锁过程.

二.使用源码验证.

   刚刚我大概画出了加锁和释放锁的流程,当然我画的可能是对的,也可能是错的,这些都需要看源码来验证.
   为了方便理解,这里引入一个简单的业务场景,有两个人a,b去银行办理业务,目前只有一个办理窗口,只能排队一个一个来,每个人大概需要二十分钟左右,业务代码很简单,大概如下所示.
在这里插入图片描述
所以现在的流程是这样的,
1.a先执行lock操作,可以抢到锁,执行业务逻辑;
2.b线程尝试获取锁失败,被阻塞;

(1) a先到了,准备抢锁.执行lock操作.
点进去lock方法,可以看到本质上还是执行的AQS中的lock方法.在这里插入图片描述
再点进去,发现是一个抽象方法,所以必然是有子类实现具体逻辑,这里有两个子类,分别对应的是公平锁和非公平锁的实现,这里以非公平锁切入,所以点进NonfairSync.
在这里插入图片描述
点进来首先执行的compareAndSetState方法,也就是我之前所说的CAS操作了,看是否能执行成功,可以的话就说明获取到锁,然后将独占线程指向当前线程,
这里是a第一个获取锁的线程,当然是可以执行成功的,所以a获取到锁直接返回了.
在这里插入图片描述
(2) a已经获取到锁,现在b执行加锁操作.
之前多余的步骤不再演示,这里b抢锁会失败,就会执行acquire方法.
在这里插入图片描述
点进来之后首先执行第一个方法tryAcquire,其实看方法名就可以见名知义,尝试获取锁,
在这里插入图片描述
点进来发现这个方法什么都每干,直接抛异常了,可能有些小伙伴直接蒙蔽了,这里其实就是典型的模板模式,指定一个方法,强制子类去实现,否则就会抛异常.所以这里选择子类的非公平锁方法去看
在这里插入图片描述
这个方法其实又是尝试获取锁的操作.但是不会获取成功,返回false.
在这里插入图片描述
执行完上述方法将会重新返回到acquire方法中,接着执行addWaiter方法.
在这里插入图片描述
addWaiter方法主要就是将当前线程封装的节点加入到等待队列中
在这里插入图片描述
enq方法就是一个自旋操作,真正将当前线程节点加到队列中.
在这里插入图片描述
这里把代码中所做的操作用图来演示,可以看到,我们加入到队列中的第一个节点并不是当前线程封装的节点,而是一个空节点,为什么要这样做呢?这里留个悬念,后面会解答这个问题.
在这里插入图片描述
现在执行完addWaiter方法往上返,开始执行acquireQueued方法.
在这里插入图片描述
在acquireQueued()方法中会执行两次循环,第一次因为shouldParkAfterFailedAcquire()方法返回false而结束,第二次执行该方法的时候,因为WaitStatus状态已经更新为-1,就会直接返回true,从而可以执行parkAndCheckInterrupt()方法,在该方法中,将b线程进行阻塞.

在这里插入图片描述
至此,两个线程a和b抢锁操作已经完.线程a获取到锁,b线程进入阻塞状态.

因文章篇幅太长,这里分为两篇博客讲解,下一篇将继续讲解解锁的过程.还有小彩蛋.
AQS详解3-源码解读(下)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员bling

义父,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值