对AQS的源码解析理解
2021/10/4 17:13:05
本文主要是介绍对AQS的源码解析理解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
我们使用常用的ReentrantLock来解析AQS是怎么工作的,仅仅是自己的一些理解,希望大家指正。
首先我们进入lock()
我们发现,源码中是使用了一个sync.lock()来调用的,那么sync是什么呢?
我们跟踪源码发现sync是ReentrantLock中的一个属性,而Sync类就是继承了我们说的AQS,这也就说明了ReentrantLock其实就是使用AQS来做到一个对于线程的阻塞和通知唤醒的管理的。我们接着向下看。
我们发现sync.lock()进来之后是一个抽象方法,这其实是一种模板模式的应用了,AQS来定义出这些方法,但是具体的实现需要落实到具体的子类上。
我们这次追踪的是非公平锁,所以我们进入第二个
我们发现代码很简单,首先是使用了一个cas的方法尝试来将state变为1,这个state是什么呢,state==0,就说明当前锁无人持有,为1就说明有线程持有锁了,若是>=2,代表的是一个重入次数
。若是cas成功,则说明当前线程是成功获取锁了,就通过setExclusiveOwnerThread()将主线程设为自己,若是cas失败,则会执行acquire方法,来获得锁。
acquire里面是使用tryAcquire尝试获取锁,当获取失败的话,就会走后面的acquireQueued,这个就是将这个线程放入到等待队列了,我们先来看tryAcquire方法
又是模板设计模式的应用,我们仍然是进入非公平锁
就是线程会获取当前的state,然后若是c == 0,那么说明当前锁无人持有,下面又是一个cas,若是锁被人持有,那么会判断一下当前持有锁的线程是不是自己,若是自己的话,是可以重入的,这也是ReentrantLock的一个特性,否则返回false
当tryAcquire为false,那么加上一个!,就可以往下走,我们再看一个addWaiter,这个其实就是将线程放入到一个等待队列了,
首先会创建一个节点,这个node节点中是包含了当前线程的,这也是实现队列的一个机制,下面先来判断了一个tail节点是否为null,也就是看当前等待队列中是否有节点,若是没有的话会执行enq(),系统会自己创建一个没有内容的哨兵节点,作为head和tail(稍后再看源码),然后才会将当前线程节点放入到队列中,也就是说,队列中的第一个线程是哨兵线程,第一个线程入队之后其实已经是两个线程节点了。
tail为null的时候会将head设置为一个新的空节点,然后tail = head;否则就是将当前节点设为tail节点。
进入等待队列的一个大致流程大概是那么多,但是我们发现此时线程还没有阻塞啊?那么线程是在哪里阻塞的呢?
我们往前看的话发现acquireQueued还没有说,我们进去看一下
核心的代码就是循环中的,首先是若是自己是队列头部的节点,会再去尝试获取锁,失败的话就走下面的一个if,里面的两个方法
这个就是来改变node节点中的waitstatus,这个值默认是0,第一次会将其改为-1,表示后续线程需要取消连接,也就是当前已经阻塞了,之后会走parkAndCheckInterrupt方法(这个才是重点)
*
代码很简单,但是需要一个LockSupport的前置知识, LockSupport就是可以提供一个类似wait和notify的作用(具体深入的理解需要下去看)看到这我们也就明白了,这个线程算是进入等待队列了,而且阻塞了。
下面我么看一下unlock();
一样的是一个sync调用的release方法
就是去尝试释放锁,释放成功的话就会调用unparkSuccessor方法对队列头部的线程发放一个许可证,也就是理解为唤醒线程
tryRelease()中还是比较简单的,就是就将state-1,之后看state是否等于0,等于0的话就返回true
大概是那么多,是一些自己的理解,希望大家指正
这篇关于对AQS的源码解析理解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-02Java管理系统项目实战入门教程
- 2024-11-02Java监控系统项目实战教程
- 2024-11-02Java就业项目项目实战:从入门到初级工程师的必备技能
- 2024-11-02Java全端项目实战入门教程
- 2024-11-02Java全栈项目实战:从入门到初级应用
- 2024-11-02Java日志系统项目实战:初学者完全指南
- 2024-11-02Java微服务系统项目实战入门教程
- 2024-11-02Java微服务项目实战:新手入门指南
- 2024-11-02Java项目实战:新手入门教程
- 2024-11-02Java小程序项目实战:从入门到简单应用