1.概念
AQS(AbstractQueuedSynchronizer),是一个用于构建锁、同步器、协作工具类的框架。

2.三要素
(1).state
根据具体实现类的不同显示不同的含义,如CountDownLatch类表示还需要倒数的数量,Semaphore类表示剩余许可证,ReentrantLock类中表示重入次数。

(2).控制线程抢锁和配合的FIFO队列

队列是用来存放等待的线程,当多个线程竞争同一把锁时,只有一个线程获取锁,其它线程就会被封装node结点加入到队列中,当锁被释放时,AQS就需要从队列中挑选一个合适的线程来占有锁。

20.AQS_头结点

(3).期望协作工具类去实现的重要方法

  • 获取锁方法
  • 释放锁方法

3.接口概览
(1).Lock

public interface Lock {
//如果锁可用就获得锁,如果锁不可用就阻塞直到锁释放
void lock();

//和lock()方法相似, 但阻塞的线程可中断,抛出java.lang.InterruptedException异常
void lockInterruptibly() throws InterruptedException;

//非阻塞方式获取锁
boolean tryLock();

//带有超时时间非阻塞方式获取锁
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

//释放锁
void unlock();

Condition newCondition();
}

20.AQS_头结点_02

(2).ReadWriteLock

public interface ReadWriteLock {
Lock readLock();

Lock writeLock();
}

20.AQS_头结点_03

4.ReentrantLock

(1).类关系图

20.AQS_java_04

(2).lock()

20.AQS_结点_05

static final class NonfairSync extends Sync {
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
}
  • 先通过CAS尝试获取锁,如果获取成功,就将锁的拥有者设置为自己
  • 否则调用AbstractQueuedSynchronizer.acquire()
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable {
public final void acquire(int arg) {
if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
}
  • 通过tryAcquire尝试获取独占锁,如果成功返回true,失败返回false
  • 如果tryAcquire失败,则会通过addWaiter方法将当前线程封装成Node添加到AQS队列尾部
static final class NonfairSync extends Sync {
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
abstract static class Sync extends AbstractQueuedSynchronizer {
final boolean nonfairTryAcquire(int acquires) {
//获得当前执行的线程
final Thread current = Thread.currentThread();
//获得state的值
int c = getState();
//state=0说明当前是无锁状态
if (c == 0) {
//通过cas操作将state的值改为1
//使用cas操作是为了避免多线程环境下存在的线程不安全问题
if (compareAndSetState(0, acquires)) {
//设置锁的拥有者为当前线程
setExclusiveOwnerThread(current);
return true;
}
}
//如果是同一个线程来获得锁,则直接增加重入次数
else if (current == getExclusiveOwnerThread()) {
//增加重入次数
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
  • 获取当前线程,判断当前的锁的状态
  • 如果state=0表示当前是无锁状态,通过cas更新state状态的值
  • 如果当前线程是属于重入,则增加重入次数
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable {
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
//tail是AQS的中表示同步队列队尾的属性,刚开始为null,所以进行enq(node)方法
Node pred = tail;
//tail不为空,说明队列中存在被阻塞的线程
if (pred != null) {
//当前线程Node的prev节点指向tail
node.prev = pred;
//通过CAS将node添加到AQS队列
if (compareAndSetTail(pred, node)) {
//CAS成功,把旧tail的next指针指向新的tail
pred.next = node;
return node;
}
}
enq(node);
return node;
}
}
  • 将当前线程封装成Node
  • 判断当前链表中的tail节点是否为空,如果不为空,则通过cas操作把当前线程的node添加到AQS队列
  • 如果为空或者cas失败,调用enq()方法通过自旋将节点添加到AQS队列
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable {
private Node enq(final Node node) {
for (;;) {
//如果是第一次添加到队列,那么tail=null
Node t = tail;
if (t == null) {
//CAS的方式创建一个空的Node作为头结点
if (compareAndSetHead(new Node()))
//此时队列中只一个头结点,所以tail也指向它
tail = head;
} else {
//进行第二次循环时,tail不为null,进入else区域。
//将当前线程的Node结点的prev指向tail,然后使用CAS将tail指向Node
node.prev = t;
if (compareAndSetTail(t, node)) {
//t此时指向tail,所以可以CAS成功,将tail重新指向Node,此时t为更新前tail的值,即指向空的头结点,t.next=node,就将头结点的后续结点指向Node,返回头结点
t.next = node;
return t;
}
}
}
}
}
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable {
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
//如果前驱为head才有资格进行锁的抢夺
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null;
failed = false;
return interrupted;
}
//如果获取锁失败,则根据节点的waitStatus决定是否需要挂起线程
if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
}
  • 获取当前节点的prev节点
  • 如果prev节点为head节点,那么它就有资格去争抢锁,调用tryAcquire抢占锁
  • 抢占锁成功以后,把获得锁的节点设置为head,并且移除原来的初始化head节点
  • 如果获得锁失败,则根据waitStatus决定是否需要挂起线程
  • 最后,通过cancelAcquire取消获得锁的操作

(3).unlock()

public class ReentrantLock implements Lock, java.io.Serializable {
public void unlock() {
sync.release(1);
}
}
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable {
public final boolean release(int arg) {
//释放锁
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
//唤醒队首线程
unparkSuccessor(h);
return true;
}
return false;
}
}
  • 释放锁
  • 唤醒队首线程
public class ReentrantLock implements Lock, java.io.Serializable {
protected final boolean tryRelease(int releases) {
//将锁的数量减1
int c = getState() - releases;
//如果释放的线程和获取锁的线程不是同一个,抛出非法监视器状态异常
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
//直到最后一次释放锁时,才会把当前线程释放
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
}
  • 将状态减掉传入的参数值(参数是1)
  • 如果结果状态为0,就将排它锁的Owner设置为null,使得其它线程有机会获取锁
  • 如果结果状态不为0,就设置state

5.CountDownLatch

public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable {
protected final boolean compareAndSetState(int expect, int update) {
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)
//把没有获取锁的线程放到等待队列中并阻塞
doAcquireSharedInterruptibly(arg);
}

private void doAcquireSharedInterruptibly(int arg) throws InterruptedException {
//将当前线程包装成Node结点
final Node node = addWaiter(Node.SHARED);
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();
if (p == head) {
int r = tryAcquireShared(arg);
if (r >= 0) {
setHeadAndPropagate(node, r);
p.next = null; // help GC
failed = false;
return;
}
}
//将线程挂起进入阻塞状态
if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}

public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}

public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
//如果state从1减为0,则唤醒所有等待的线程
doReleaseShared();
return true;
}
return false;
}

private void doReleaseShared() {
for (;;) {
Node h = head;
if (h != null && h != tail) {
int ws = h.waitStatus;
if (ws == Node.SIGNAL) {
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
continue;
//唤醒线程
unparkSuccessor(h);
}
else if (ws == 0 && !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue;
}
if (h == head)
break;
}
}
}

(1).CountDownLatch

public class CountDownLatch {
//1.构造方法
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}

//2.等待
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}

//3.释放
public void countDown() {
sync.releaseShared(1);
}

private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L;

//设置state的值
Sync(int count) {
setState(count);
}

//获取state值
int getCount() {
return getState();
}

protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}

protected boolean tryReleaseShared(int releases) {
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
}
}

20.AQS_开发语言_06

(2).Semaphore

public class Semaphore implements java.io.Serializable {
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}

public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}

//1.获取许可证
public void acquire() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}

abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 1192457210091910933L;

Sync(int permits) {
setState(permits);
}

final int getPermits() {
return getState();
}

//获取许可证
final int nonfairTryAcquireShared(int acquires) {
for (;;) {
int available = getState();
int remaining = available - acquires;
if (remaining < 0 || compareAndSetState(available, remaining))
return remaining;
}
}

protected final boolean tryReleaseShared(int releases) {
for (;;) {
int current = getState();
int next = current + releases;
if (next < current)
throw new Error("Maximum permit count exceeded");
if (compareAndSetState(current, next))
return true;
}
}

final void reducePermits(int reductions) {
for (;;) {
int current = getState();
int next = current - reductions;
if (next > current) // underflow
throw new Error("Permit count underflow");
if (compareAndSetState(current, next))
return;
}
}

final int drainPermits() {
for (;;) {
int current = getState();
if (current == 0 || compareAndSetState(current, 0))
return current;
}
}
}

//非公平
static final class NonfairSync extends Sync {
private static final long serialVersionUID = -2694183684443567898L;

NonfairSync(int permits) {
super(permits);
}

protected int tryAcquireShared(int acquires) {
return nonfairTryAcquireShared(acquires);
}
}

//公平
static final class FairSync extends Sync {
private static final long serialVersionUID = 2014338818796000944L;

FairSync(int permits) {
super(permits);
}

protected int tryAcquireShared(int acquires) {
for (;;) {
if (hasQueuedPredecessors())
return -1;
int available = getState();
int remaining = available - acquires;
if (remaining < 0 ||
compareAndSetState(available, remaining))
return remaining;
}
}
}
}

20.AQS_java_07

(3).ReentrantLock

public class ReentrantLock implements Lock, java.io.Serializable {
public ReentrantLock() {
sync = new NonfairSync();
}

public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}

//加锁
public void lock() {
sync.lock();
}

//解锁
public void unlock() {
sync.release(1);
}

//获取重入次数
public int getHoldCount() {
return sync.getHoldCount();
}

abstract static class Sync extends AbstractQueuedSynchronizer {
abstract void lock();

protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
//state等于0,则释放锁
//不等于0,只需要将重入次数减1即可
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
}

static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;

final void lock() {
acquire(1);
}

protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
} else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}

static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;

final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}

protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
}

20.AQS_头结点_08

4.自己实现AQS

public class OneShotLatch {
private final Sync sync = new Sync();

public void signal() {
sync.releaseShared(0);
}

public void await() {
sync.acquireShared(0);
}

private class Sync extends AbstractQueuedSynchronizer {

@Override
protected int tryAcquireShared(int arg) {
return (getState() == 1) ? 1 : -1;
}

@Override
protected boolean tryReleaseShared(int arg) {
setState(1);

return true;
}
}


public static void main(String[] args) throws InterruptedException {
OneShotLatch oneShotLatch = new OneShotLatch();
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "尝试获取latch,获取失败那就等待");
oneShotLatch.await();
System.out.println("开闸放行" + Thread.currentThread().getName() + "继续运行");
}
}).start();
}
Thread.sleep(5000);
oneShotLatch.signal();
}
}
Thread-1尝试获取latch,获取失败那就等待
Thread-0尝试获取latch,获取失败那就等待
Thread-2尝试获取latch,获取失败那就等待
Thread-4尝试获取latch,获取失败那就等待
Thread-3尝试获取latch,获取失败那就等待
Thread-5尝试获取latch,获取失败那就等待
Thread-6尝试获取latch,获取失败那就等待
Thread-7尝试获取latch,获取失败那就等待
Thread-8尝试获取latch,获取失败那就等待
Thread-9尝试获取latch,获取失败那就等待
开闸放行Thread-1继续运行
开闸放行Thread-6继续运行
开闸放行Thread-2继续运行
开闸放行Thread-3继续运行
开闸放行Thread-4继续运行
开闸放行Thread-9继续运行
开闸放行Thread-0继续运行
开闸放行Thread-8继续运行
开闸放行Thread-7继续运行
开闸放行Thread-5继续运行