IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> AQS详解3-源码解读(上) -> 正文阅读

[Java知识库]AQS详解3-源码解读(上)

此篇文章不再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-源码解读(下)

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 21:36:26  更:2022-03-13 21:39:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:49:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码