JUC 一:AQS对CLH的改进

153 阅读2分钟

AQS(AbstractQueuedSynchronizer)是Java并发包中的一个核心组件,它为许多同步组件(如ReentrantLock、Semaphores、CountDownLatch等)提供了一个框架。它的内部使用了一个名为CLH(Craig, Landin, and Hagersten)队列的变种来管理等待的线程。

CLH队列原始设计是一个简单的自旋锁,它使用链表结构并允许新加入的节点自旋等待其前驱节点的标志位变化,而不是自旋等待锁本身。

AQS对CLH做了以下几点改进或调整以适应更广泛的同步结构:

  1. 双向队列:AQS使用了一个双向队列,而不是CLH的简单单向队列。这允许AQS进行取消等待节点的操作,因为它可以从等待线程链表的中间移除节点。

  2. 条件队列:除了主同步队列外,AQS还提供了一个条件队列,它允许线程在某些条件下进行等待。这是实现Condition接口和await/signal操作的关键。

  3. 共享模式和独占模式:AQS支持两种模式:共享模式和独占模式。这为实现读写锁等数据结构提供了基础。

  4. 状态管理:AQS引入了一个名为state的整型变量来帮助管理同步状态,而不仅仅是锁定/未锁定。这使得AQS可以基于state来实现多种类型的同步组件。

  5. 等待策略:而不是简单地自旋等待,AQS为等待线程提供了几种不同的等待策略,包括自旋、自旋后进入阻塞状态等。这提高了效率并降低了CPU的使用。

  6. 中断支持:AQS为等待线程提供了响应中断的能力,允许线程在等待时被中断。

总的来说,尽管AQS的设计基于CLH队列,但它在此基础上加入了多种功能和优化,使其成为Java并发包中的一个非常强大和灵活的同步工具。