`
uule
  • 浏览: 6352552 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

AQS

 
阅读更多

 大白话聊聊Java并发面试问题之谈谈你对AQS的理解?

AQS的理解

 

 

一、ReentrantLock和AQS的关系

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

这个是java并发基本API的使用,应该每个人都是学过的,所以我们直接看一下代码就好了:


 

你这时可能会问,这个跟AQS有啥关系?关系大了去了!因为java并发包下很多API都是基于AQS来实现的加锁和释放锁等功能的,AQS是java并发包的基础类。

 

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

 

那么AQS的全称是什么呢?AbstractQueuedSynchronizer,抽象队列同步器。

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

 

说白了,ReentrantLock内部包含了一个AQS对象,也就是AbstractQueuedSynchronizer类型的对象。这个AQS对象就是ReentrantLock可以实现加锁和释放锁的关键性的核心组件。

 

 

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

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

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

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



 

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

 

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

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


 

 

其实看到这儿,大家应该对所谓的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此时就是加锁失败。

 

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


 

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

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

 

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


 

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

 

整个过程,参见下图:


 

 

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

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

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

 

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


 

三、总结

其实一句话总结AQS就是一个并发包的基础组件,用来实现各种锁,各种同步组件的。它包含了【state变量、加锁线程、等待队列】等并发中的核心组件。

  • 大小: 10.7 KB
  • 大小: 8.6 KB
  • 大小: 12.3 KB
  • 大小: 19.9 KB
  • 大小: 28.6 KB
  • 大小: 26.1 KB
  • 大小: 27.8 KB
  • 大小: 30.6 KB
分享到:
评论

相关推荐

    aqs_demo.rar

    《AQS同步器与Redisson锁在Java高并发API及SpringBoot中的应用》 在Java并发编程领域,AbstractQueuedSynchronizer(AQS)是一个非常重要的基础组件,它是Java并发包java.util.concurrent中实现锁和同步器的核心...

    AQS源码分析 (1).pdf

    AQS全称为AbstractQueuedSynchronizer,是java中用于构建锁以及其他同步器的一个框架。在多线程的编程中,同步问题是一个非常重要的问题,而AQS正是为了解决这个问题而生的。 首先,我们需要了解的是AQS的核心思想...

    Java并发之AQS详解.pdf

    Java并发之AQS详解 AbstractQueuedSynchronizer(AQS)是 Java 并发编程中的一个核心组件,提供了一套多线程访问共享资源的同步器框架。AQS 定义了两种资源共享方式:Exclusive(独占)和 Share(共享)。在 AQS 中...

    JDK_AQS解析

    ### JDK_AQS解析 #### 概述 在Java并发编程中,`AbstractQueuedSynchronizer`(简称AQS)是实现锁和其他同步工具的基础框架。AQS位于`java.util.concurrent`包下,通过模板方法设计模式实现了锁的底层机制。本文将...

    Java volatile与AQS锁内存可见性

    从JUC中的AQS引入,讲解Java volatile与AQS锁内存可见性

    aqs中文翻译-by sushengmiyan.pdf

    java大师doug lean 在JDK1.5版本的AQS论文中文翻译。 许可:本作品的全部或部分在不为牟利或商业利益为目的的,且在第一页引述本声明及全完整引用的前提下,以数码或硬拷贝形式供个人或课堂使用的复制或分发不收取...

    AQS流程图.html

    java锁AQS基础逻辑

    AQS流程图ReentranLock.vsdx

    AQS流程图ReentranLock.vsdx

    JUC核心类AQS的底层原理

    ### AQS核心原理与ReentrantLock的实现细节 #### AQS(AbstractQueuedSynchronizer)内部结构 AQS作为Java并发工具包(JUC)中的一个核心抽象类,其设计目的是为了实现各种同步器(如锁、信号量等)。AQS主要通过三...

    juc aqs java

    juc 的aqs介绍。

    java并发编程:juc、aqs

    `AQS`(AbstractQueuedSynchronizer)是JUC库中的一个关键组件,它是一个抽象基类,为构建自定义的同步器提供了基础框架。AQS通过内部维护一个基于链表的等待队列,有效地管理线程的同步和唤醒,从而实现锁和其他同步...

    Java并发编程:深入解析抽象队列同步器(AQS)及其在Lock中的应用

    本文深入探讨了Java并发编程的关键组件——抽象队列同步器(AQS)及其在ReentrantLock的应用。AQS是处理线程同步问题的高效工具,是Java并发编程中的核心。文章首先简要介绍了并发编程领域的先驱Doug Lea。重点在于...

    aqs_java_

    《Java并发编程:深入理解AQS》 在Java编程领域,多线程和并发处理是不可或缺的一部分,而Java.util.concurrent库则是实现并发控制的核心工具。本文将深入探讨该库中的重要组件——AbstractQueuedSynchronizer(AQS...

    AQS源码阅读笔记,画了两三天的AQS...

    AQS源码阅读笔记 AQS(AbstractQueuedSynchronizer)是Java并发编程中的一种同步器框架,它提供了一个队列来管理线程的排队和唤醒机制。下面是AQS源码阅读笔记的详细解释: 1. `ReentrantLock` 的 `unlock()` 方法...

    Java AQS详解.docx

    【Java AQS详解】 AbstractQueuedSynchronizer (AQS) 是 Java 并发库中的一个核心组件,它是实现高效并发控制的基础。AQS 提供了一种基于队列的线程同步机制,允许开发者构建自定义的锁和同步器。在Java并发编程中...

    AQS的底层原理.zip

    《AQS的底层原理》 在Java并发编程领域,AbstractQueuedSynchronizer(简称AQS)是一个核心组件,它是Java并发库中的基石,被许多并发工具类如ReentrantLock、Semaphore、CountDownLatch等作为基础框架来实现。AQS...

    AQS和JUC知识点讲解

    《AQS和JUC知识点详解》 在Java并发编程领域,AbstractQueuedSynchronizer(AQS)和Java Util Concurrency(JUC)是两个至关重要的概念。它们为开发高效、线程安全的多线程程序提供了强大的工具。本文将深入解析这...

Global site tag (gtag.js) - Google Analytics