并发编程:JUC下的同步实现之AQS理解

1:AQS是什么

AQS:全称AbstractQueuedSynchronizer(抽象类的队列式同步器). 是JUC包下的一个抽象类. aqs因为是抽象类,本身并不提供同步的接口,但JUC下的其他同步组件都是基于aqs来进行实现同步的,比如(:ReentrantLock、CountDownLatch、Semaphore)这些都是继承自aqs.所以aqs在并发编程中是至关重要的知识点.

2:实现AQS的类

AQS支持线程抢占两种锁——独占锁和共享锁:

  • 实现独占锁的类:ReentrantLock、ReentrantReadWriteLock.WriteLock
  • 实现共享锁的类:ReentrantReadWriteLock.ReadLock、CountDownLatch、CyclicBarrier、Semaphore

独占锁Exclusive:同一个时刻只能被一个线程占有,它又可分为:
        公平锁:按照线程在队列中的排队顺序,先到者先拿到锁
        非公平锁:当线程要获取锁时,无视队列顺序直接去抢锁,谁抢到就是谁的
共享锁Share:同一时间点可以被多个线程同时占有.

3:AQS的实现原理

     FIFO线程等待队列

      AQS的实现依赖内部的同步队列,也就是FIFO的双向队列,如果当前线程竞争锁失败,那么AQS会把当前线程以及等待状态信息构造成一个Node(如下图)加入到同步队列中,同时再阻塞该线程。当获取锁的线程释放锁以后,会从队列中唤醒一个阻塞的节点(线程)。 

      队列内部维护的是一个FIFO的双向链表,这种结构的特点是每个数据结构都有两个指针,分别指向直接的后继节点和直接前驱节点,所以双向链表可以从任意一个节点开始很方便的访问前驱和后继。每个Node其实都是由线程封装的,当线程争抢锁失败后会封装成Node加入到AQS队列中去。

 volatile int state(共享资源)

      state用来表示当前的同步状态,根据当前state的值,来判断当前释放处于锁定状态,或者是其他状态。当state=1时代表当前对象锁已经被占用,其他线程来加锁时则会失败,失败的线程被放入一个FIFO的等待队列中,然后会被UNSAFE.park()操作挂起,等待已经获得锁的线程释放锁才能被唤醒。我们继承AQS时,根据自己的需求,实现一些方法,其中就是通过修改state的值来维持同步状态。主要方法如下:

//获取当前同步状态state的值
int getState()
//设置当前同步状态state的值
void setState(int newState)
//使用CAS设置当前同步状态的值,方法能够保证设置同步状态时的原子性;
//参数expect为state的预期旧值,而update是需要修改的新值,若设置成功,方法返回true,否则false
boolean compareAndSetState(int expect, int update)

4:AQS相关的关系脑图

 脑图引用的文章:  AQS简介(附脑图)_Linias的博客-CSDN博客

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值