JUC中的AQS底层详细超详解

🚀 优质资源分享 🚀

学习路线指引(点击解锁) 知识定位 人群定位
🧡 Python实战微信订餐小程序 🧡 进阶级 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战💛 入门级 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

**摘要:**当你使用java实现一个线程同步的对象时,一定会包含一个问题:你该如何保证多个线程访问该对象时,正确地进行阻塞等待,正确地被唤醒?

本文分享自华为云社区《JUC中的AQS底层详细超详解,剖析AQS设计中所需要考虑的各种问题!》,作者: breakDawn 。

java中AQS究竟是做什么的?

当你使用java实现一个线程同步的对象时,一定会包含一个问题:

你该如何保证多个线程访问该对象时,正确地进行阻塞等待,正确地被唤醒?

关于这个问题,java的设计者认为应该是一套通用的机制

因此将一套线程阻塞等待以及被唤醒时锁分配的机制称之为AQS

全称 AbstractQuenedSynchronizer

中文名即抽象的队列式同步器 。

基于AQS,实现了例如ReentenLock之类的经典JUC类。

AQS简要步骤

  1. 线程访问资源,如果资源足够,则把线程封装成一个Node,设置为活跃线程进入CLH队列,并扣去资源
  2. 资源不足,则变成等待线程Node,也进入CLH队列
  3. CLH是一个双向链式队列, head节点是实际占用锁的线程,后面的节点则都是等待线程所对应对应的节点

AQS的资源state

state定义

AQS中的资源是一个int值,而且是volatile的,并提供了3个方法给子类使用:

private volatile int state;
protected final int getState() {
 return state;
}
protected final void setState(int newState) {
 state = newState;
}
// cas方法
compareAndSetState(int oldState, int newState);

如果state上限只有1,那么就是独占模式Exclusive,例如 ReentrantLock

如果state上限大于1,那就是共享模式Share,例如 Semaphore、CountDownLatch、ReadWriteLock,CyclicBarrier

已经有CAS方法了,为什么资源state还要定义成volatile的?

对外暴露的getter/setter方法,是走不了CAS的。而且setter/getter没有被synchronized修饰。所以必须要volatile,保证可见性

这样基于AQS的实现可以直接通过getter/setter操作state变量,并且保证可见性,也避免重排序带来的影响。比如CountDownLatch,ReentrantReadWriteLock,Semaphore都有体现(各种getState、setState)

对资源的操作什么时候用CAS,什么使用setState?

volatile的state成员有一个问题,就是如果是复合操作的话不能保证复合操作的原子性

因此涉及 state增减的情况,采用CAS

如果是state设置成某个固定值,则使用setState

AQS的CLH队列

为什么需要一个CLH队列

这个队列的目的是为了公平锁的实现

即为了保证先到先得,要求每个线程封装后的Node按顺序拼接起来。

CLH本质?是一个Queue容器吗

不是的,本质上是一个链表式的队列

因此核心在于链表节点Node的定义


除了比较容易想到的prev和next指针外

还包含了该节点内的线程

以及 waitStatus 等待状态

4种等待状态如下:

  • CANCELLED(1): 因为超时或者中断,节点会被设置为取消状态,被取消的节点时不会参与到竞争中的,他会一直保持取消状态不会转变为其他状态;
  • SIGNAL(-1):后继节点的线程处于等待状态,而当前节点的线程如果释放了同步状态或者被取消,将会通知后继节点,使后继节点的线程得以运行
  • CONDITION(-2) ÿ
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值