JAVA AQS源码深度讲解和分析

为方便理解,本文章以非公平锁ReentrantLock()为例作为突破讲解方法lock。

前置知识:JAVA AQS源码分析前置知识-CSDN博客

ReentrantLock的原理

Lock接口的实现类,基本都是通过聚合了一个队列同步器的子类完成线程访问控制的

 从最简单的lock方法开始看看公平和非公平

 公平锁和非公平锁的lock()方法唯一的区别就在于公平锁在获取同步状态时多了一个限制条件:hasQueuedPredecessors()-----公平锁加锁时判断等待队列中是否存在有效节点的方法

以非公平锁ReentrantLock()为例作为突破---方法lock()

对比公平锁和非公平锁的tryAcquire()方法的实现代码,其实差异就在于非公平锁获取锁时比公平锁中少了一个判断!hasQueuedPredecessors(),hasQueuedPredecessors()中判断了是否需要排队,导致公平锁和非公平锁的差异如下:

  • 公平锁:公平锁讲究先来后到,线程在获取锁时,如果这个锁的等待队列中已经有线程在等待,那么当前线程就会进入到等待队列中;
  • 非公平锁:不管是否有等待队列,如果可以获取到锁,则立刻占有锁对象。也就是说队列的第一个排队线程苏醒后,不一定就是排头的这个线程获得锁,它还需要参加竞争锁(存在线程竞争的情况下),后来的线程可能不讲武德插队夺锁了。

源码解读 

1. lock()

  • 非公平锁,先试图直接抢占锁(调用compareAndSetState),若未抢占成功才调用acquire方法。
  • 即:不管是否有等待队列,都先进行锁的抢夺

  • 公平锁,直接调用acquire方法。

2.acquire()

  • 类似一个责任链,先尝试获取锁(tryAcquire),若失败则加入队列(addWriter)并坐稳队列(acquireQueued)
  • return false:继续推进条件,走下一个方法
  • return true:结束

2.1. tryAcquire(arg)

  • 流程:先判断锁状态,若为0(未锁定)则尝试争抢锁,否则判断当前持有锁的是否是当前线程,否则返回fase
  • 对比:公平锁和非公平的的区别是是否进行!hasQueuedPredecessors() 的判断,即是否判断队列中是否有等待的节点。
  • 非公平锁:

  • 公平锁:

2.2.addwaiter

  • 从enq方法中我们可以知道在双向链表中,第一个节点为虚节点(也叫做哨兵节点),其实不存储任何信息,只是占位。真正的第一个有数据的节点,是从第二个节点开始的

  • 假如此时有线程C进入

2.3.acquireQueued(addWeiter(Node.EXCLUSIVE), arg)

3. unlock()

总览:

  • tryRelease

4.其他线程unlock后的同时其他线程的acquireQueued

5. acquireQueued执行失败或取消执行时

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/707253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言————结构体

接下来我们来了解C语言中很重要的内容:结构体。虽然到现在我们可以创建常量,变量,数组,但是存储的都是相同类型的数据,如果我们需要写入不同数据类型的信息怎么办,例如常见的身份证上的信息,有身…

springboot+vue+mysql+easyexcel实现文件导出+导出的excel单元格添加下拉列表

Excel导出 EasyExcel官方文档 官方文档本身写的非常详细,我就是根据官方文档内的写Excel里web中的写实现的导出 后端 对象 需要写一个实体类 其中涉及到一些用到的EasyExcel的注解 ColumnWidth(20) 列宽设为20,自定义的,放在实体类上面是…

Postgresql中触发器的使用

在PostgreSQL中,触发器是一种特殊类型的函数,它会自动在数据库上执行特定操作之前或之后触发。这些操作通常是INSERT、UPDATE或DELETE语句。触发器可以用来执行数据校验、自动更新或维护表之间的关联。 触发器组件 触发器函数:这是实际执行…

binwalk安装记录和burpsuite安装记录

我的虚拟机环境是Ubuntu20.04 python有2.7的和3.8的 [[#binwalk|binwalk]] [[#binwalk#pip|pip]][[#binwalk#安装 sasquatch|安装 sasquatch]][[#binwalk#安装 jefferson|安装 jefferson]][[#binwalk#安装 ubi_reader|安装 ubi_reader]][[#binwalk#安装 yaffshiv|安装 yaffshi…

JavaWeb——005 -- 请求响应 分层解耦(Postman、三层架构、IOC、DI、注解)

目录 一、请求 1、Postman(接口测试工具) 1.1、介绍 ②、安装 2、简单参数 1.1、原始方式 1.2、SpringBoot方法 ③、小结 3、实体参数 3.1、简单实体对象 3.2、复杂实体对象 3.3、小结 4、数组集合参数 ①、数组​编辑 ②、集合 ③、小结…

Alist访问主页显示空白解决方法

文章目录 问题记录问题探索和解决网络方案问题探究脚本内容查看 最终解决教程 问题记录 访问Alist主页显示空白,按F12打开开发人员工具 ,选择控制台,报错如下 index.75e31196.js:20 Uncaught TypeError: Cannot assign to read only property __symbo…

python|闲谈2048小游戏和数组的旋转及翻转和转置

目录 2048 生成数组 n阶方阵 方阵旋转 顺时针旋转 逆时针旋转 mxn矩阵 矩阵旋转 测试代码 测试结果 翻转和转置 2048 《2048》是一款比较流行​的数字游戏​,最早于2014年3月20日发行。原版2048由Gabriele Cirulli首先在GitHub上发布,后被移…

【Day59】代码随想录之动态规划_583两个字符串的删除操作_72编辑距离

文章目录 动态规划理论基础动规五部曲:出现结果不正确: 1. 583两个字符串的删除操作2. 72编辑距离 动态规划理论基础 动规五部曲: 确定dp数组 下标及dp[i] 的含义。递推公式:比如斐波那契数列 dp[i] dp[i-1] dp[i-2]。初始化d…

选择排序的简单介绍

选择排序是一种简单直观的排序算法,其原理如下: 1. 遍历数组,找到最小(或最大)的元素,并将其与数组的第一个元素交换位置。 2. 接着在剩下的元素中找到最小(或最大)的元素&#xff…

Uniapp在IOS系统打包测试流程

大家好我是咕噜美乐蒂,很高兴又和大家见面了!UniApp 是一种基于 Vue.js 的跨平台应用开发框架,可以用于快速构建同时支持多个平台(包括iOS、Android、Web 等)的应用程序。在 iOS 系统上打包和测试 UniApp 应用的流程可…

园区水费收费管理系统

园区水费收费管理系统是专为园区或小区的水费管理而设计的系统,旨在提高水费收费效率、精准监测水费使用情况,简化管理流程,为园区管理方和居民提供便捷、高效的水费管理解决方案。该系统结合了数字化技术和智能化管理手段,通过线…

『NLP学习笔记』图解 GPT-2(可视化 Transformer 语言模型)

图解 GPT-2(可视化 Transformer 语言模型) 文章目录 一. GPT-2和语言模型1.1. 什么是语言模型1.2 Transformer的语言模型1.3 和BERT的不同1.4 Transformer 组件的演变1.4.1 encoder组件1.4.2 decoder组件1.4.3 只有decoder组件的decoder模块1.5 GPT-2内部结构1.6 GPT-2内部结构…

P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G python解法

P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) nint(input()) arrlist(map(int,input().split())) arr.sort() sumarr[0] total_sum0 #一开始以为单纯排列就行了,然后将之前累计的时间求和 for i…

非同质化权益(NFR):重塑当代商业市场的新范式

每天五分钟讲解一个互联网知识,大家好我是啊浩说互联网 随着区块链技术的日益成熟和数字资产的普及,非同质化权益(Non-Fungible Rights,简称NFR)开始崭露头角,并在当代商业市场中引发了一场深刻的变革。NFR…

pg_rman部署及使用

PG_RMAN部署及使用 PGSQL推出开源备份工具pg_rman,类似于oracle的rman备份策略,实现了全量、增量和归档等多重备份方式,可以很灵活的管理PGSQL数据库的备份,支持在线和基于PITR的备份恢复方式。 1、使用postgres用户部署 [post…

动态规划-状态转移(O(n))

获取生成数组中的最大值 1.题目 2.思路 其实只要看透该题的本质 并不难,应用动态规划,题目就已经给出了状态方程的式子。 首先规定好maxn的大小,防止溢出。定义nums数组。定义一个函数,写入状态方程式子。最后定义一个变量与数…

【数据结构】数组

第一章、为什么数组的下标一般从0开始编号 提到数组,读者肯定不陌生,甚至还会很自信地说,数组很简单。编程语言中一般会有数组这种数据类型。不过,它不仅是编程语言中的一种数据类型,还是基础的数据结构。尽管数组看起…

Openstack云计算架构及前期服务搭建

openstack介绍 Openstack是一个开源的云计算管理平台项目,由几个主要的组件组合起来完成具体工作,支持几乎所有的云环境,项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台 ----百度百科 Openstack是一个云操作系统&a…

STM32开发(屏幕驱动ST7735S-SPI方式)用RT-Thread驱动测试

前言 使用ST7735S屏幕驱动,方便学习LVGL通过结构体的方式来管理相关函数和变量通讯协议和硬件驱动层进行解耦 驱动 配置(用于对接硬件) st7735s_conf.h // // Created by shchl on 2024/2/28. //#ifndef STM32F407V4T6_RTOS_ST7735S_CON…

css常用的选择器介绍

CSS(层叠样式表)选择器是CSS规则的一部分,它用于选择和定位网页上的元素,以便将样式应用到这些元素上。CSS选择器的种类繁多,每种选择器都有其特定的用途、特点和效率。在这篇文章中,我们将讨论一些常用的C…