1. 前言
抽象队列同步器AbstractQueuedSynchronizer,是用来构建java.util.concurrent包中的锁和其他并发相关的组件的基础类。它通过使用一个int类型的state来表示同步状态,将没有获取锁的线程构造成一个节点,放到一个先进先出队列里,这个队列是使用链表实现的。当一个线程释放锁后,会将这个队列里的节点对应的线程唤醒。
AQS是抽象类,所以使用时需要继承AQS,实现所有protected方法。子类应该定义为非public的内部帮助类(helper class),用来实现外部类的同步属性。
2. AQS中的主要方法
AQS是基于模板方法模式设计的,所以使用时需要继承AQS并重写指定的方法。然后将AQS组合在自定义同步组件的实现中,并调用AQS提供的模板方法,而这些模板方法将会调用重写的方法。
2.1 子类可重写的方法
重写AQS指定的方法时,需要使用AQS提供的下面3个方法来获取,修改同步状态。
- getState():获取当前同步状态
- setState():设置当前同步状态
- compareAndSetStatus(int expect, int update):使用CAS设置同步状态,该方法可以保证原子性
同步器可重写的方法如下:
| 方法 |
描述 |
| protected protected boolean tryAcquire(int arg) |
尝试独占式获取同步状态。这个方法应该先检查对象的状态是否允许独占式获取,如果是将获取同步状态 |
| protected boolean tryRelease(int arg) |
尝试独占式设置状态以释放锁 |
| protected int tryAcquireShared(int arg) |
尝试共享式获取同步状态。这个方法应该先检查对象的状态是否允许共享式获取,如果是将获取同步状态。 返回负数表示失败,其他表示成功 返回值详细说明: a negative value on failure; zero if acquisition in shared mode succeeded but no subsequent shared-mode acquire can succeed; and a positive value if acquisition in shared mode succeeded and subsequent shared-mode acquires might also succeed, in which case a subsequent waiting thread must check availability. (Support for three different return values enables this method to be used in contexts where acquires only sometimes act exclusively.) Upon success, this object has been acquired. |
| protected boolean tryReleaseShared(int arg) |
尝试共享式设置状态以释放锁 |
| protected boolean isHeldExclusively() |
当前线程是否在独占模式下占用同步状态(synchronization) |
2.2 模板方法
实现自定义同步组件时,将会调用AQS提供的模板方法,部分方法如下:
| 方法 |
描述 |
| public final void acquire(int arg) |
独占式获取同步状态,忽略中断。通过至少一次调用tryAcquire方法实现 如果获取成功,则会返回,否则,线程将会进入同步队列,可能会重复地阻塞,非阻塞(unblocking),调用tryAcquire,直到成功 |
| public final void acquireInterruptibly(int arg) |
在acquire(int arg)基础上增加了中断响应 |
| public final boolean tryAcquireNanos(int arg, long nanosTimeout) |
在acquireInterruptibly(int arg)基础上增加了超时限制 |
| public final void acquireShared(int arg) |
共享式获取同步状态,忽略中断。通过先至少调用一次tryAcquireShared实现。与独占式获取的主要区别是在同一时刻可以有多个线程获取到同步状态 |
| public final void acquireSharedInterruptibly(int arg) |
在acquireShared(int arg)基础上增加了中断响应 |
| public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) |
在acquireSharedInterruptibly(int arg)基础上增加了超时限制 |
| public final boolean release(int arg) |
独占式释放同步状态。该方法会在释放同步状态后,将同步队列中第一个节点包含的线程唤醒 |
| public final boolean releaseShared(int arg) |
共享式释放同步状态 |
| public final Collection getQueuedThreads() |
获取等待在同步队列上的线程集合 |
上面一共有三类方法:独占式获取与释放同步状态、共享式获取与释放同步状态和查询同步队列中的等待线程情况。
3. 代码示例
下面这个类是官方给的示例。互斥(独占)锁是一个自定义同步组件,它在同一时刻只允许一个线程占有锁。
/**
* Here is a non-reentrant mutual excl

本文详细解析了AbstractQueuedSynchronizer(AQS)在Java并发编程中的核心作用,包括如何通过继承AQS创建自定义锁,关键方法的重写和模板方法的使用,以及同步队列的实现和同步状态的获取与释放。实例演示了互斥锁的实现,对比了Condition接口与Object监视器的区别,并深入剖析了Condition的内部机制。
最低0.47元/天 解锁文章
308

被折叠的 条评论
为什么被折叠?



