并发编程第7篇,AQS一些简单的概念

AQS基本的概念

aqs全称为AbstractQueuedSynchronizer 是一个抽象同步队列,它提供了一个FIFO队列,可以看成是一个用来实现同步锁以及其他涉及到同步功能的核心组件,常见的有:ReentrantLock、CountDownLatch等。

AQS是一个抽象类,主要是通过继承的方式来使用,它本身没有实现任何的同步接口,仅仅是定义了同步状态的获取以及释放的方法来提供自定义的同步组件。

AQS底层的实现 结合CAS compareAndSwapInt实现

AQS源码解读

 

NonfairSync 非公平锁

FairSync 公平锁

公平锁与非公平锁最大的区别:就是在做cas操作的是时候加上  !hasQueuedPredecessors()

必须遵循公平竞争

 

AQS核心参数

1.Node结点 采用双向链表的形式存放正在等待的线程 waitStatus状态、thread等到锁的线程

CANCELLED,值为1,表示当前的线程被取消;

SIGNAL,值为-1,释放资源后需唤醒后继节点;

CONDITION,值为-2,  等待condition唤醒;

PROPAGATE,值为-3,工作于共享锁状态,需要向后传播,比如根据资源是否剩余,唤醒后继节点;

值为0,表示当前节点在sync队列中,等待着获取锁。

  1. Head 头结点 等待队列的头结点
  2. Tail 尾结点  正在等待的线程
  3. State 锁的状态 0 无锁、1已结获取锁, 当前线程重入不断+1
  4. exclusiveOwnerThread 记录锁的持有

 

公平锁实现原理图:

 

非公平锁实现原理图:


Lock锁基本实现原理

Lock锁原理 基于javaAQS类封装 在获取锁的时候AQS类中有一个状态state

+1,当前线程不断重入的时候都会不断1+,当在释放锁的时候state-1;

最终state为0 该锁没有被任何线程获取到,没有抢到锁的线程,会存在一个

双向的链表中。

公平锁与非公平锁在获取锁的时候多了一个判断 (!hasQueuedPredecessors() &
阻塞和唤醒用的apilocksupport,为了这个效率只会唤醒阻塞队列中head节点.next 线程。

AQS中为什么头结点是为空的

头结点可以简单理解就是可以不用参加排队,表示已经获取到锁的线程,已经在aqs类中已经记录绑定获取到锁的线程,所以head结点直接设置为null,防止浪费空间内存。

AQS核心的方法

tryAcquire ---重试获取锁

tryRelease--释放锁

acquireSharedInterruptibly---将当前线程变为阻塞状态

releaseShared  ---让等待的线程,被唤醒 同时状态变为0

思考:面试中经如果问AQS的原理怎么回答?AQS如何实现公平锁和非公平锁

每一行代码都有它的涵义,多问一句为什么;别怕,理清思路,一切代码都是数据的流动和转化,耐心一点,慢慢积累!一起加油!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值