AQS acquireQueued
时间: 2024-05-18 17:14:11 浏览: 98
AQS的acquireQueued方法是在tryAcquire执行失败后,用于将当前线程加入到等待队列,并在适当的时候阻塞线程。具体流程如下:
1. 首先,使用addWaiter方法将当前线程添加到等待队列中,该方法会创建一个节点并将其插入到等待队列的尾部。
2. 然后,调用shouldParkAfterFailedAcquire方法来判断是否应该阻塞当前线程。该方法会根据前驱节点的等待状态来决定是否需要阻塞当前线程。
- 如果前驱节点的等待状态为Node.SIGNAL,表示前驱节点释放锁之后会唤醒当前节点,此时应该阻塞当前线程。
- 如果前驱节点的等待状态大于0,表示前驱节点取消了等待,需要将当前节点的前驱节点设置为前驱节点的前驱节点,直到找到一个等待状态不大于0的节点为止。然后将当前节点插入到该节点之后。
- 如果前驱节点的等待状态既不是Node.SIGNAL,也不大于0,则使用compareAndSetWaitStatus方法将前驱节点的等待状态设置为Node.SIGNAL,表示当前节点需要被唤醒。
3. 最后,根据shouldParkAfterFailedAcquire方法的返回值来判断是否需要阻塞当前线程。如果shouldParkAfterFailedAcquire方法返回false,表示不需要阻塞当前线程,则acquireQueued方法会一直自旋直到成功获取锁为止。如果shouldParkAfterFailedAcquire方法返回true,表示需要阻塞当前线程,则调用LockSupport.park方法阻塞当前线程,直到被唤醒为止。
<span class="em">1</span><span class="em">2</span><span class="em">3</span>
#### 引用[.reference_title]
- *1* *2* *3* [AQS核心流程解析-acquire方法](https://blog.csdn.net/IToBeNo_1/article/details/123404852)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"]
[ .reference_list ]
阅读全文