前言:
AQS(AbstractQueuedSynchronizer)是 Java 中用于实现锁和同步器的基础框架,它使用了一种名为 CLH(Craig, Landin, and Hagersten)的队列算法。
解释:
CLH 队列算法是一种基于链表的公平锁实现方式,它的核心思想是将所有请求锁的线程加入到一个队列中,并且在队列中维护一个虚拟的前驱节点。当一个线程需要获取锁时,它会以原子操作的方式将自己添加到队列的尾部,然后等待前驱节点释放锁。这种方式可以保证所有请求锁的线程按照先来先服务的顺序获取锁,从而达到公平性的效果。
应用:
在 AQS 中,CLH 队列算法被用于实现 ReentrantLock、ReentrantReadWriteLock 、 Semaphore和CountDownLatch 等同步器。AQS 将队列作为同步器状态的一部分,使用一个 head
指针来表示队列头,一个 tail
指针来表示队列尾,以及一个 waitStatus
来表示节点的状态信息。
原理:
当一个线程请求锁时,它会创建一个节点并将其加入到队列尾部,然后通过自旋(compareAndSet)等待自己成为队列头部的节点。当前驱节点释放锁时,它会唤醒后继节点,并将自己从队列中移除。这种方式可以保证在多线程并发访问时,所有请求锁的线程能够按照先来先服务的顺序获取锁,并且能够有效避免死锁和饥饿等问题。
因此,AQS 中使用 CLH 队列算法来实现同步器的加锁和释放,从而达到了高效、公平、可扩展的效果。