Java 并发高频面试题:聊聊你对 AQS 的理解?

JAVA面试题分享五百四十九:JUC中的AQS底层详细超详解,剖析AQS设计中所需要考虑的各种问题 / cas方法如果state上限只有1,那么就是独占模式Exclusive,例如 ReentrantLock如果state上限大于1,那就是共享模式Share,例如 Semaphore、CountDownLatch、ReadWriteLock,CyclicBarrier对外暴露的getter/setter方法,是走不了CAS的。而且setter/getter没有被synchronized修饰。所以必须要volatile,保证可见性。 阅读详情

一、 写在前面

这篇文章,我们来聊聊面试时一个比较有杀伤力的问题:聊聊你对AQS的理解?

之前有同学反馈,去互联网公司面试,面试官聊到并发时就问到了这个问题。当时那位同学内心估计受到了一万点伤害。。。

因为首先,很多人可能连AQS是什么都不知道。或者仅仅是听说过AQS这个名词,但是可能连全称怎么拼写都不知道。

更有甚者,可能会说:AQS?是不是一种思想?我们平时开发怎么来用AQS?

总结起来,很多同学都对AQS有一种云里雾里的感觉,如果用搜索引擎查一下AQS是什么,估计看几篇文章就直接放弃了,因为密密麻麻的文字,实在是看不懂!

所以基于上述痛点,这篇文章就用最简单的大白话配合N多张手绘图,给大家讲清楚AQS到底是什么?

让各位同学面试被问到这个问题时,不至于不知所措。

二、ReentrantLock和AQS的关系

首先来看看,如果用java并发包下的ReentrantLock来加锁和释放锁,是个什么样的感觉?

这个学过java的同学应该都会吧,毕竟是java并发基本API的使用,我们直接看一下代码:

640?wx_fmt=png

上面那段代码应该不难理解,无非就是搞一个Lock对象,然后加锁和释放锁。

你这时可能会问,这个跟AQS有啥关系?

关系大了去了!因为java并发包下很多API都是基于AQS来实现的加锁和释放锁等功能的,AQS是java并发包的基础类。

举个例子,比如说ReentrantLock、ReentrantReadWriteLock底层都是基于AQS来实现的。

那么AQS的全称是什么呢?

AbstractQueuedSynchronizer,抽象队列同步器

给大家画一个图,看一下ReentrantLock和AQS之间的关系。

640?wx_fmt=png

我们看上图,说白了,ReentrantLock内部包含了一个AQS对象,也就是AbstractQueuedSynchronizer类型的对象。

这个AQS对象就是ReentrantLock可以实现加锁和释放锁的关键性的核心组件。

三、ReentrantLock加锁和释放锁的底层原理

好了,现在如果有一个线程过来尝试用ReentrantLock的lock()方法进行加锁,会发生什么事情?

很简单,这个AQS对象内部有一个核心的变量叫做state,是int类型的,代表了加锁的状态。

初始状态下,这个state的值是0。

另外,这个AQS内部还有一个关键变量,用来记录当前加锁的是哪个线程,初始化状态下,这个变量是null。

640?wx_fmt=png

接着线程1跑过来调用ReentrantLock的lock()方法尝试进行加锁,这个加锁的过程,直接就是用CAS操作将state值从0变为1。

(关于CAS,之前专门有文章做过详细阐述,大家可以自行阅读了解)

如果之前没人加过锁,那么state的值肯定是0,此时线程1就可以加锁成功。

一旦线程1加锁成功了之后,就可以设置当前加锁线程是自己。所以大家看下面的图,就是线程1跑过来加锁的一个过程。

640?wx_fmt=png

其实看到这儿,大家应该对所谓的AQS有感觉了。说白了,就是并发包里的一个核心组件,里面有state变量、加锁线程变量等核心的东西,维护了加锁状态。

你会发现,ReentrantLock这种东西只是一个外层的API,内核中的锁机制实现都是依赖AQS组件的。

这个ReentrantLock之所以用Reentrant打头,意思就是他是一个可重入锁。

可重入锁的意思,就是你可以对一个ReentrantLock对象多次执行lock()加锁和unlock()释放锁,也就是可以对一个锁加多次,叫做可重入加锁。

大家看明白了那个state变量之后,就知道了如何进行可重入加锁!

其实每次线程1可重入加锁一次,会判断一下当前加锁线程就是自己,那么他自己就可以可重入多次加锁,每次加锁就是把state的值给累加1,别的没啥变化。

接着,如果线程1加锁了之后,线程2跑过来加锁会怎么样呢?

我们来看看锁的互斥是如何实现的?

线程2跑过来一下看到,哎呀!state的值不是0啊?所以CAS操作将state从0变为1的过程会失败,因为state的值当前为1,说明已经有人加锁了!

接着线程2会看一下,是不是自己之前加的锁啊?当然不是了,**“加锁线程”**这个变量明确记录了是线程1占用了这个锁,所以线程2此时就是加锁失败。

给大家来一张图,一起来感受一下这个过程:

640?wx_fmt=png

接着,线程2会将自己放入AQS中的一个等待队列,因为自己尝试加锁失败了,此时就要将自己放入队列中来等待,等待线程1释放锁之后,自己就可以重新尝试加锁了

所以大家可以看到,AQS是如此的核心!AQS内部还有一个等待队列,专门放那些加锁失败的线程!

同样,给大家来一张图,一起感受一下:

640?wx_fmt=png

接着,线程1在执行完自己的业务逻辑代码之后,就会释放锁!他释放锁的过程非常的简单,就是将AQS内的state变量的值递减1,如果state值为0,则彻底释放锁,会将“加锁线程”变量也设置为null!

整个过程,参见下图:

640?wx_fmt=png

接下来,会从等待队列的队头唤醒线程2重新尝试加锁。

好!线程2现在就重新尝试加锁,这时还是用CAS操作将state从0变为1,此时就会成功,成功之后代表加锁成功,就会将state设置为1。

此外,还要把**“加锁线程”**设置为线程2自己,同时线程2自己就从等待队列中出队了。

最后再来一张图,大家来看看这个过程。

640?wx_fmt=png

四、总结

OK,本文到这里为止,基本借着ReentrantLock的加锁和释放锁的过程,给大家讲清楚了其底层依赖的AQS的核心原理。

基本上大家把这篇文章看懂,以后再也不会担心面试的时候被问到:谈谈你对AQS的理解这种问题了。

其实一句话总结:AQS就是一个并发包的基础组件,用来实现各种锁,各种同步组件的。

它包含了state变量、加锁线程、等待队列等并发中的核心组件。

END

如有收获,请划至底部,点击“在看”,谢谢!

640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1

欢迎长按下图关注公众号石杉的架构笔记

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1

Java并发编程面试题——JUC专题 1.1AQS是什么?1.2唤醒线程时,AQS为什么从后往前遍历?1.3AQS为什么用双向链表,(为啥不用单向链表)?1.4AQS为什么要有一个虚拟的head节点1.5ReentrantLock的底层实现原理1.6ReentrantLock的公平锁和非公平锁的区别1.7ReentrantReadWriteLock如何实现的读写锁2.1说下你熟悉的阻塞队列?2.2虚假唤醒是什么?3.1线程池的7个参数3.2线程池的状态有什么,如何记录的?3.3线程池常见的拒绝策略3.4线程池执行流程3.5线程池为什么添加空任务 阅读详情

相关推荐

50道Java经典面试题总结

(1)Semaphore 同步器特征:经典的信号量,通过计数器控制对共享资源的访问Semaphore(int count): 创建拥有 count 个许可证的信号量acquire()/acquire(int num) : 获取 1/num 个许可证release/release(int num) : 释放 1/num 个许可证(2)CountDownLatch 同步器特征:必须发生指定数量的事件后才可以继续运行 (比如赛跑比赛,裁判喊出 3,2,1 之后大家才同时跑)

2401_83470102的博客 1020

JAVA面试题|AQS详细剖析

JAVA基础篇面试题 文章目录JAVA基础篇面试题1. 线程等待唤醒的实现方法2. 介绍一下LockSupport3. AQS是什么4. AQS的核心原理5. 公平锁与非公平锁的区别6. 请讲述非公平锁加锁解锁的具体流程 1. 线程等待唤醒的实现方法 Object对象中的wait()方法可以让线程等待,使用Object中的notify()方法唤醒线程; 必须都在同步代码块内使用; 调用wait,notify的对象是加锁对象; notify必须在wait后执行才能唤醒; wait后能释放锁对象,线程处

qq_37419449的博客 1万+

Java后端高频面试真题

什么是内存溢出,什么是内存泄漏?- CPU 飙高系统反应慢怎么排查?_ 关于什么是 jvm?- 有没有排查过线上 oom 的问题,如何排查的- 说一下你对双亲委派的理解- CPU 飙高系统反应慢怎么排查?- JVM 如何判断一个对象可以被回收- G1 垃圾收集的特点,为什么低延迟- JVM 分代年龄为什么是 15次?可以25 次吗?- 一个空Object 对象的占多大空间?- 什么是Java 虛拟机,为什么要使用?- JVM 为什么使用元空间替换了永久代?

interviewpass的博客 605

Java 并发高频面试题:聊聊你对 AQS 的理解?——ReentrantLock和AQS的关系

ReentrantLock和AQS的关系 首先来看看,如果用java并发包下的ReentrantLock来加锁和释放锁,是个什么样的感觉? 这个学过java的同学应该都会吧,毕竟是java并发基本API的使用,我们直接看一下代码: 上面那段代码应该不难理解,无非就是搞一个Lock对象,然后加锁和释放锁。 你这时可能会问,这个跟AQS有啥关系? 关系大了去了!因为java并发包下很多API都是基于AQS来实现的加锁和释放锁等功能的,AQS是java并发包的基础类。 举个例子,比如说ReentrantLock

your_棒棒糖的博客 263

汇总药用数据库(Pubchem,bingdingDB,Chembl,ExcapeDB)数据

记载一下如何汇总4大数据库的数据

recher_He1107的博客 3394

从零开始:DJI-F450无人机硬件组装全流程解析

本文详细解析了DJI-F450无人机的硬件组装全流程,从开箱清点到焊接、机械组装、飞控系统搭建、电路整合及调试试飞。重点介绍了电调焊接、机臂安装、飞控校准等关键步骤的实用技巧和常见问题解决方案,帮助无人机爱好者从零开始完成专业级组装。

weixin_29210759的博客 623

AQS(AbstractQueuedSynchronizer)

AQS 【原创】Java并发编程系列14 | AQS源码分析 图解AQS: 我画了35张图就是为了让你深入 AQS AbstractQueuedSynchronizer是Java并发包java.util.concurrent的核心基础组件,是实现Lock的基础。 AQS AbstractQueuedSynchronizer 抽象队列同步器Java 并发高频面试题:聊聊你对 AQS 的理解? AbstractQueuedSynchronizer是Java并发包java.util...

wanglei1598的博客 487

手把手教你用STM32F030实现功率MOS双脉冲测试(附完整电路图)

本文详细介绍了如何使用STM32F030微控制器搭建功率MOSFET双脉冲测试平台。通过分析双脉冲测试原理,提供了完整的硬件电路设计、驱动电路选型、软件时序生成方法,并指导如何利用示波器捕获和分析开关波形,从而评估功率器件的动态特性与开关损耗。

juice的博客 717

Java并发编程

BAT面试官为什么都喜欢问并发编程的问题? synchronized实现原理、CAS无锁化的原理、AQS是什么、Lock锁、ConcurrentHashMap的分段加锁的原理、线程池的原理、java内存模型、volatile说一下吗、对java并发包有什么了解?一连串的问题 写一些java web系统,运用一些框架和一些第三方技术,写一些类似于crud的业务逻辑,把各种技术整合一下,写一些crud而已,没什么技术含量。很多人可能写好几年的代码,都不会用到多少java并发包下面的东西 如果说你要面试一些

li709650465的博客 382

PowerDesigner16.5下载和安装教程

一、软件下载 1.下载地址(不用复制,直接点击下载链接即可):链接:https://pan.baidu.com/s/1MSnWHWt3SO2Uz5dt9AANAg提取码:z9kk 二、软件安装 1.下载安装包(包含安装文件、汉化包、注册文件) 2.下载后文件内容如下 3....

cicong2374的博客 10万+

DeepSpeed Zero3 Offload实战:从GCC版本检查到环境配置的完整避坑指南

本文是一份针对DeepSpeed Zero3 Offload部署的完整避坑指南。针对训练中常见的`AttributeError: ‘DeepSpeedCPUAdam‘ object has no attribute ‘ds_opt_adam`报错,文章深入剖析了其根源在于GCC编译器版本过低。指南提供了从系统GCC版本深度探查、安全启用高版本GCC环境,到DeepSpeed一致性安装验证的全链路实战方案,旨在帮助用户构建稳定的大模型训练环境。

weixin_29070721的博客 474

大厂Java面试高频题:这些知识点你掌握了吗?

大厂Java面试高频题远不止这些,但上述六大模块几乎涵盖了一二面的绝大部分。真正拉开差距的,是你能否在压力下说出“为什么”,而不是“是什么”。比如HashMap为什么用红黑树而不是平衡二叉树?因为红黑树的旋转次数更少,插入效率更高;为什么AQS用双向队列而不是单链?因为需要支持取消等待和公平锁的排队唤醒。这些细节决定了你是否真的读懂了源码。如果你能针对每一个知识点,都想象出一个面试官追杀死角的场景,并提前准备好逻辑清晰的回答,那么下一次推开面试间大门时,你手里的就不只是简历,而是整套从容应对的底牌。

qq_35974860的博客 15

大模型之Spring AI实战系列(二十六):Spring Boot + DeepSeek 实战指南:构建AI聊天应用

在人工智能技术飞速发展的今天,大型语言模型已经成为了推动技术创新的重要力量。DeepSeek作为国内领先的大型语言模型提供商,其推出的DeepSeek系列模型在多个领域都展现出了卓越的性能。本文将详细介绍如何使用Spring Boot框架集成DeepSeek API,构建一个简单的AI聊天应用。我们将实现两个核心功能:普通文本生成和流式文本生成。

寻道AI,探索AI无限可能! 2265

Java面试高频考点精讲:从基础到进阶的实战解析

本文系统解析Java面试从基础到进阶的核心考点,涵盖并发编程、JVM原理、集合框架源码及设计模式。重点探讨如何从死记硬背转向深度理解,通过实战案例剖析HashMap、ConcurrentHashMap、线程池等高频面试题,帮助开发者构建系统性知识图谱,提升解决实际问题的能力。

kubernetes8ctl的博客 633

《MATLAB项目实战》,专栏目录和介绍

MATLAB 是一款强大且广泛应用的数值计算和数据可视化软件工具,它提供了一个高效、简洁的编程环境,使用户能够进行从简单的矩阵运算到复杂的多维数据分析的各种计算任务。无论是在人工智能、计算机视觉、图像处理还是其他领域,MATLAB 都能够提供精准、快速的解决方案,因此成为了全球科研人员、工程师以及数据分析师的得力工具。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 6478

Feature ‘alsa‘ was enabled, but the pre-condition ‘config.unix && !config.qnx && libs.alsa‘ failed解决

这个问题主要是Qt多媒体插件中缺少了ALSA音频库,所以我们需要自行先编译ALSA 在执行./configure的时候,配置项中ALSA为no Qt Multimedia: ALSA ................................... no GStreamer 1.0 .......................... no GStreamer 0.10 ......................... no Video for Linux .............

有问题或资源连接有缺失的可以私信公众号新潮看世界获取 2590

Java高频面试题总结

设计面试面试题 一个单例还能写出花来吗? 单例模式的7个问题 面试官问你单例设计模式,问问自己你真的了解单例吗?小单例,不简单! 漫画:AOP 面试造火箭事件始末 动态代理总结,面试你要知道的都在这里,无废话! linux 面试题 凉了!张三同学没答好「进程间通信」,被面试官挂了… 懵了,阿里面试官叫我讲讲mmap? 框架篇:小白也能秒懂的Linux零拷贝原理 从根上理解用户态与内核态 讲讲用户空间和内核空间 你管这破玩意叫 IO 多路复用? 阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO

养歌的博客 817

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Java并发编程必知必会面试连环炮

目录1 面试官为什么都喜欢问并发编程的问题?2 synchronized关键字的底层原理是什么?3 能聊聊你对CAS的理解以及其底层实现原理可以吗?4 ConcurrentHashMap实现线程安全的底层原理到底是什么?5 JDK中的AQS理解吗?AQS的实现原理是什么?6 线程池的底层工作原理可以吗?7 线程池的核心配置参数都是干什么的?平时我们应该怎么用?8 如果在线程池中使用无界阻塞队列会发生什么问题?9 你知道如果线程池的队列满了之后,会发生什么事情吗?10 如果线上机器突然宕机,线程池的阻塞队列中

赵广陆 1144

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: Java基础之—反射(非常重要)
下一篇: Java 面试题大集合,2019最新最常见面试题加答案
普通网友
博客等级 码龄4年 3126粉丝 192原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值