AQS AbstractQueuedSynchronizer 同步器框架

文章详细介绍了AQS(AbstractQueuedSynchronizer)在Java并发编程中的作用,包括其维护的state和线程等待队列,以及如何通过实现不同的获取和释放资源的方法来创建自定义同步器。ReentrantLock作为独占锁的示例,CountDownLatch和Semaphore作为共享资源的例子分别展示了它们的使用场景和工作原理。此外,还提到了Node结点的状态和waitStatus字段在同步队列管理中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AQS AbstractQueuedSynchronizer 同步器框架
Exclusive 独占(只有一个线程能执行), 如 ReentrantLock
Share 共享(多个线程同时执行), 如 Semaphore / CountDownLatch
独占和共享, 如 ReentrantReadWriteLock

AQS 维护了一个共享资源状态 
volatile int state 和一个 FIFO 线程等待队列,
自定义同步器只需要实现共享资源状态 state 的获取与释放方式(通过state的get/set/CAS)
isHeldExclusively() 该线程是否正在独占资源, 只有用到 condition 才需要去实现它
tryAcquire(int) 
独占方式, 尝试获取资源,成功返回 true,失败返回 false
tryRelease(int) 
独占方式, 尝试释放资源,成功返回 true,失败返回 false

tryAcquireShared(int) 共享方式, 尝试获取资源
负数表示失败
0 表示成功,但没有剩余可用资源
正数表示成功,有剩余资源

tryReleaseShared(int) 共享方式, 尝试释放资源,
如果释放后允许唤醒后续等待结点返回 true,否则返回 false

ReentrantLock 
state 初始化为 0,表示未锁定状态
A 线程 lock() 时,会调用 tryAcquire() 独占该锁并将 state+1, 
其他线程再 tryAcquire() 时就会失败,直到A线程 unlock() 到 state=0(即释放锁)为止,
其它线程才有机会获取该锁
释放锁之前,A线程自己是可以重复获取此锁的(state会累加)
tryLock() 尝试加锁,成功返回 true, 失败返回 false, 非阻塞
lock() 阻塞加锁,线程会阻塞直到加到锁

不管公平锁还是非公平锁,底层实现都会使用 AQS 来排队
线程使用 lock() 加锁时,如果是公平锁,会先检查 AQS 队列中是否存在线程在排队,如果有线程排队,则当前线程也进行排队,如果是非公平锁,则不会检查是否有线程在排队,而是直接竞争锁
不管是公平锁还是非公平锁,一旦没竞争到锁,都会进行排队,当锁释放时,都是唤醒排在最前面的线程

CountDownLatch 闭锁/发令枪,用于一个或多个线程等其他几个线程完成某些工作之后再执行
构造函数 确定数量
减一操作 每当一个线程执行完毕后,countDown() 一次,state 会 CAS 减 1
阻塞通过 调用 await() 方法的线程会进入 AQS 等待队列,当计数器为 0 时,会将 AQS 中排队的线程依次唤醒,继续后续动作

CyclicBarrier 几个线程相互等待,等大家都准备好了,再开始执行
Semaphore 信号量, 设置许可个数,表示同时允许最多多少个线程使用该信号量,通过 acquire() 获取许可,如果没有许可可用则线程阻塞进入AQS等待队列,可以通过 release() 释放许可,释放许可会唤醒 AQS 中等待的线程
Exchanger 用于两个线程之间交换数据

Node 结点状态 waitStatus
Node 结点是对每一个等待获取资源的线程的封装,包含了需要同步的线程本身及其等待状态,如是否被阻塞、是否等待唤醒、是否已经被取消等
变量 waitStatus 则表示当前 Node 结点的等待状态
CANCELLED(1) 表示当前结点已取消调度,当 timeout 或被中断(响应中断的情况下), 会触发变更为此状态
SIGNAL(-1) 表示后继结点在等待当前结点唤醒,后继结点入队时,会将前继结点的状态更新为 SIGNAL
CONDITION(-2) 表示结点等待在 Condition 上,当其他线程调用了 Condition 的 signal() 方法后,
CONDITION 状态的结点将从等待队列转移到同步队列中,等待获取同步锁
PROPAGATE(-3) 共享模式下,前继结点不仅会唤醒其后继结点,同时也可能会唤醒后继的后继结点
0 新结点入队时的默认状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我三师弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值