内容来自《Offer 来了:Java 面试核心知识点精进(原理篇)》
AQS(Abstract Queued Synchronizer)是一个抽象的队列同步器,通过维护一个共享资源状态(volatile int state)和一个先进先出(FIFO)的线程等待队列来实现一个多线程访问共享资源的同步框架。
AQS 为每个共享资源都设置一个共享资源锁,线程在需要访问共享资源时首先需要获取共享资源说,如果获取到了共享资源锁,便可以在当前线程中使用该共享资源,如果获取不到,则将该线程放入线程等待队列,等待下一次资源调度,具体的流程如图3-14所示。许多同步类的实现都依赖于AQS,例如常用的 ReentrantLock、Semaphore、CountDownLatch。
Abstract Queued Synchronizer 维护了一个 volatile int 类型的变量,用于表示当前的同步状态。volatile 虽然不能保证操作的原子性,但是能保证当前变量 state 的可见性。
state 的访方式有三种:getState()、setState() 和 compareAndSetState(),均是原子操作,其中,compareAndSetState的实现依赖于Unsafe compareAndSwapInt()。具体的JDK 代码实现如下:
//返回共享资源状态,此操作的内存语义为 volatile 修饰的原子读操作
protected final int getState() {
return state;
}
//设置共享资源状态,此操作的内存语义为volatile修饰的原子写操作
protected final void setState(int newState) {
state = newState;
}
//自动将同步状态设置为给定的更新状态值(如果当前状态值等于预期值)
//此操作的内存语义为 volatile 修饰的原子读写操作
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}