队
列同步器
AbstractQueuedSynchronizer是用来构建锁或者其他同步组件基础的框架,它使用了一个int成员表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作。
使用方式:继承
提供的三个方法:getState(),setState(int newState),compareAndSetState(int expect,int update)。这三个方法能够保证状态的改变是安全的。子类推荐被定义为自定义同步组件的静态内部类,同步器自身没有实现任何同步接口,它仅仅是定义了若干同步状态获取和释放的方法来 供自定义同步组件使用,同步器既可以支持独占式地获取同步状态,也可以支持共享式地获 取同步状态,这样就可以方便实现不同类型的同步组件(ReentrantLock、ReentrantReadWriteLock和CountDownLatch等)
同步器模板方法基本上分为三类:独占式获取与释放同步状态,共享式获取与释放同步状态和查询同步队列中的等待线程情况。
下面是一个独占锁的示例:
package com.dong9.leke.aqs;
import com.sun.corba.se.impl.orbutil.concurrent.Sync;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* @classname Mutex
* @description
* @date 2021/3/24 13:52
* @created by weiwensi
*/
public class Mutex implements Lock {
// 静态内部类,自定义同步器
private static class Sync extends AbstractQueuedSynchronizer {
//是否处于占用状态
//isHeldExclusively() 当前同步器是否再独占模式下被线程占用,一般该方法表示是否被当前线程占用。
protected boolean isHeldExclusively() {
return getState() == 1;
}
// 当状态为0的时候获取锁
//独占式获取同步状态,实现该方法需要查询当前并判断同步状态是否符合预期,然后再进行cas设置同步状态
public boolean tryAcquire(int acquires) {
//如果经过cas设置成功,则代表获取了同步状态。
if (compareAndSetState(0, 1)) {
//
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
// 释放锁,将状态设置为0
//独占式获取同步状态,返回值大于等于0的值,表示获取成功,反之获取失败
protected boolean tryRelease(int releases) {
if (getState() == 0)
throw new IllegalMonitorStateException();
setExclusiveOwnerThread(null);
setState(0);
return true;
}
// 返回一个Condition,每个condition都包含了一个condition队列
Condition newCondition() {
return new ConditionObject();
}
}
// 仅需要将操作代理到Sync上即可
private final Sync sync = new Sync();
public void lock() {
sync.acquire(1);
}
public boolean tryLock() {
return sync.tryAcquire(1);
}
public void unlock() {
sync.release(1);
}
public Condition newCondition() {
return sync.newCondition();
}
public boolean isLocked() {
return sync.isHeldExclusively();
}
public boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
}
上面的代码通过静态内部类继承AQS队列同步器并重写父类 方法,通过调用父类的行为,再内部类的外部类里使用内部类,实现上锁,解锁。
再AQS队列同步器源码如下:

通过valatile保证state变量的内存可见,并且防止指令重排,


通过调用Unsafe的原子操作类,使用cas算法进行cas操作。