当前位置:   article > 正文

从 ArrayBlockingQueue 探究 AQS 细节 — 条件队列篇_为什么条件队列为什么用单向链表

为什么条件队列为什么用单向链表

开篇语

条件队列是 AQS 中最容易被忽视的一个细节。大部分时候,我们都用不上条件队列,但是这并不说明条件队列就没有用处了,它反而是我们学习生产者-消费者模式的最佳教材。

什么是条件队列

条件队列是指一个阻塞队列,其中的元素是等待某个条件成立的线程。在 Java 的同步机制中,条件队列通常用于实现线程等待和唤醒的操作。当条件不满足时,线程会被加入到条件队列中等待;当条件满足时,线程会被从条件队列中移除并继续执行。

AQS 中的条件队列

AbstractQueuedSynchronizer 中的条件队列是一个单向链表,每个节点代表一个等待线程。条件队列的头节点是一个特殊的节点,表示等待队列的头部。当条件不满足时,线程会被加入到条件队列的尾部等待;当条件满足时,线程会从条件队列中移除并加入到同步队列中等待获取锁。

AbstractQueuedSynchronizer 中的条件队列是通过内部维护的等待队列和同步队列实现的。当线程调用 await() 方法时,它会被加入到等待队列中等待条件满足。

当有其他线程调用了条件队列的 signal() 方法,线程则会从条件队列中移除,并加入到同步队列中等待获取锁。

方法解析

await

该方法的作用是将当前线程加入条件队列并阻塞,直到被唤醒或中断。

  1. public final void await() throws InterruptedException {
  2. if (Thread.interrupted())
  3. throw new InterruptedException();
  4. Node node = addConditionWaiter();
  5. int savedState = fullyRelease(node);
  6. int interruptMode = 0;
  7. while (!isOnSyncQueue(node)) {
  8. LockSupport.park(this);
  9. if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
  10. break;
  11. }
  12. if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
  13. interruptMode = REINTERRUPT;
  14. if (node.nextWaiter != null) // clean up if cancelled
  15. unlinkCancelledWaiters();
  16. if (interruptMode != 0)
  17. reportInterruptAfterWait(interruptMode);
  18. }
  19. 复制代码
  1. 如果线程被中断过,那么直接抛出中断异常
  2. 创建一个 Condition 类型的节点,并插入到等待
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/692967
推荐阅读