首页 > 其他 > 详细

深入理解AQS

时间:2021-05-26 09:22:43      阅读:21      评论:0      收藏:0      [点我收藏+]

一、什么是AQS

AQS:用来构建锁或其他同步器组件的重量级基础框架及整个JUC体系的基石,通过内置的FIFO队列来完成资源获取线程的排队工作,并通过一个int类型变量表示持有锁的状态。如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁的分配。主要通过CLH队列的变体实现,将暂时获取不到锁的线程加入到队列中,这个队列就是AQS抽象的表现。它将请求共享资源的线程封装成队列的节点(Node),通过CAS自旋以及LockSupport.park()的方式,维护state变量的状态,使并发达到同步的控制效果。

CLH队列:Craig、Landin and Hagersten队列,是一个单向链表,AQS中的队列是CLH变体的虚拟双向队列,虚拟的双向队列即不存在队列实例,仅存在节点之间的关联关系。

java.util.concurrent.locks.AbstractOenableSynchronizer;

技术分享图片

解释:是用来构建锁或者其他同步器组件的重量级基础框架及整个JUC体系的基石,通过内置的FIFO(先进先出)队列来完成资源获取线程的排队工作,并通过一个int类变量表示持有锁的状态

 技术分享图片

 和AQS有关的类:

技术分享图片

ReentrantLock:

技术分享图片

 CountDownLatch

技术分享图片

ReentrantReadWriteLock:

技术分享图片

Semaphore:

技术分享图片

锁和AQS的关系:锁面向锁的使用者,定义了程序员和锁交互的使用层API,隐藏了实现细节

同步器AQS是锁的实现

二、AQS源码分析

AQS使用一个volatile的int类型的成员变量来表示同步状态,通过内置的 FIFO队列来完成资源获取的排队工作将每条要去抢占资源的线程封装成 一个Node节点来实现锁的分配,通过CAS完成对State值的修改。

技术分享图片

AQS的同步状态state成员变量  零说明没有资源占用,自由状态可以办理  大于等于1 有线程占用资源

AQS的CLH队列

技术分享图片

AQS同步队列的基本结构

技术分享图片


                         AQS底层是怎么排队的 :是用LockSupport.park()来进行排队的

三、通过ReentrantLock中的非公平锁进行分析

主要是通过以下几个方法进行实现的:

通过银行办理业务的例子来深入了解:

  三个线程A,B,C来银行窗口办理业务,服务窗口每次只能服务一个人,初识的时候窗口是没人的!

lock()

  这边线程A拿到了去窗口办理业务的机会,通过compareAndSetState比较并交换,将AQS中变量state设置成1

技术分享图片

acquire() 

  线程A已经占用了窗口,线程B只能走acquire这个方法

技术分享图片

 tryAcquire()


技术分享图片


  技术分享图片


技术分享图片

 在来看acquire() 的方法,B线程返回false,取反的是true,往下面看下一个方法

技术分享图片

addWaiter()

 

  完成B节点的入队,通过enq源码可以知道,B线程第一次并没有进行入队,到第二次循环才将B线程入队返回

技术分享图片

技术分享图片

 

深入理解AQS

原文:https://www.cnblogs.com/zhangzhixi/p/14811475.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!