- 同步队列器 AQS(AbstractQueuedSynchronizer)是用来构建锁或自定义同步组件的基础框架,它是用一个volatile修饰的int成员变量表示同步状态,结合内置的队列完成线程获取资源的排队工作。
- 使用方式是继承同步队列器,主要使用更改同步状态的3个方法:getState(),setState(int newState),compareAndSetState
- 自定义同步组件仅仅定义了若干同步状态获取和释放的方法,既支持独占式获取,也支持共享式获取同步状态,实现不同类型的同步组件,如:ReentrantLock,ReentrantReadWriteLock,CountDownLatch等。
自定义同步器可重写的方法
方法 | 描述 |
tryAccquire | 独占式获取同步状态 |
tryRelease | 独占式释放同步状态 |
tryAccquireShared | 共享式获取同步状态 |
tryReleaseShared | 共享式释放同步状态 |
isHeldExclusively | 该方法是否被当前线程独占 |
同步器提供的模板方法
方法 | 描述 |
acquire | 独占式获取 |
acquireInterruptibly | 与acquire相同,但是响应中断 |
tryAcquireNanos | 同acquireInterruptibly,增加了超时限制 |
acquireShared | 共享式获取 |
acquireSharedInterruptibly | 与acquireShared相同,但是响应中断 |
tryAcquireSharedNanos | 同acquireSharedInterruptibly,增加了超时限制 |
release | 独占式释放同步状态 |
releaseShared | 共享式释放同步状态 |
getQueuedThreads | 获取等待在同步队列上的线程集合 |
同步队列器的实现分析
同步队列
当前线程获取同步状态失败时,同步器会将当前线程以及等待状态等信息构造成Node节点加入内置的同步队列,同时当前线程阻塞,当同步状态释放,会把首节点的线程唤醒,使其再次尝试获取同步状态。
独占式同步状态的获取和释放
同步器维护一个同步队列,获取状态失败的线程都会被加入到队列中,并在队列中自旋,移出队列的条件是:前驱节点为头结点且成功获取了同步状态;释放同步状态时,调用tryRealase方法,然后唤醒头结点的后继节点。
共享式获取
共享式和独占式的区别是:同一时刻能否有多个线程同时获取到同步状态。对于能够支持多个线程同时访问的并发组件,tryReleaseShared方法必须确保同步状态线程安全释放,一般是通过循环和CAS保证。
独占式超时获取
在指定的时间内获取同步状态,获取成功则返回true.它和独占式获取同步状态的主要区别在于未获取到同步状态时的处理逻辑:
前者:会使当前线程等待nanosTimeout纳秒,如果在等待期间没有获取同步状态,将会从等待逻辑中自动返回。
后者:未获取到同步状态时,会使当前线程一直处于等待状态。