基础 - AQS 源码解读(一)


简介
AQS听起来很高大上的样子,实际上它就是AbstractQueuedSynchronizer类的缩写,它是构建锁或者其他同步组件的基础框架。在基于AQS构建的同步器中,只能在一个时刻发生阻塞,从而降低上下文切换的开销,提高了吞吐量。同时在设计AQS时充分考虑了可伸缩行,因此J.U.C中所有基于AQS构建的同步器均可以获得这个优势。

直接讲AbstractQueuedSynchronizer抽象类会让你云里雾里,所以从Lock讲起好理解一些,毕竟大多数人没看过这篇的也会用Lock,我是一个负责人的人,讲原理必讲源码,只有从源码中提取出来的原理才是正确的,其他途径得到的原理都要抱着怀疑的态度。

Lock 接口

public interface Lock

Lock 方法

// 重入锁
void lock();
// 等待过程中,可响应中断(获取锁成功不能响应)
void lockInterruptibly() throws InterruptedException;
// 尝试获取锁,获取成功返回true,否则返回false
boolean tryLock();
// 带等待超时时间的锁
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
// 解锁
void unlock();
// 条件(一个Lock创建的条件自动绑定改lock)
Condition newCondition();

ReentrantLock 类

public class ReentrantLock implements Lock, java.io.Serializable

如果排除内部类不算,Java中只有ReentrantLock实现了Lock接口。

ReentrantLock 属性

private final Sync sync;

ReentrantLock 只有一个属性,公平锁和非公平锁都是Sync的实现。

ReentrantLock 构造函数

// 默认使用非公平锁
public ReentrantLock() {
    sync = new ReentrantLock.NonfairSync();
}
// 指定是否使用公平锁
public ReentrantLock(boolean fair) {
    sync = fair ? new ReentrantLock.FairSync() : new ReentrantLock.NonfairSync();
}

ReentrantLock 方法

// 重入锁
public void lock() {
    sync.lock();
}
// 可以响应中断的锁
public void lockInterruptibly() throws InterruptedException {
    sync.acquireInterruptibly(1);
}
// 非阻塞锁
public boolean tryLock() {
    return sync.nonfairTryAcquire(1);
}
// 带超时时间非阻塞锁
public boolean tryLock(long timeout, TimeUnit unit)
        throws InterruptedException {
    return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
// 解锁
public void unlock() {
    sync.release(1);
}
// 创建绑定条件
public Condition newCondition() {
    return sync.newCondition();
}
// 查询当前线程保持锁定的个数
public int getHoldCount() {
    return sync.getHoldCount();
}
// 查询当前线程是否保持此锁定
public boolean isHeldByCurrentThread() {
    return sync.isHeldExclusively();
}
// 查询此锁定是否由任意线程保持
public boolean isLocked() {
    return sync.isLocked();
}
// 判断lock锁是公平锁还是非公平锁
public final boolean isFair() {
    return sync instanceof ReentrantLock.FairSync;
}
// 返回目前拥有此锁的线程
protected Thread getOwner() {
    return sync.getOwner();
}
// 判断是否有处于等待lock的状态
public final boolean hasQueuedThreads() {
    return sync.hasQueuedThreads();
}
// 判断线程是否处于等待lock的状态
public final boolean hasQueuedThread(Thread thread) {
    return sync.isQueued(thread);
}
// 获取正等待获取此锁定线程数
public final int getQueueLength() {
    return sync.getQueueLength();
}
// 获取正等待获取此锁定线程
protected Collection<Thread> getQueuedThreads() {
    return sync.getQueuedThreads();
}
// 查询是否有线程在condition.await状态中
public boolean hasWaiters(Condition condition) {
    if (condition == null)
        throw new NullPointerException();
    if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
        throw new IllegalArgumentException("not owner");
    return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
}
// 获取同一个Condition类的等待线程数
public int getWaitQueueLength(Condition condition) {
    if (condition == null)
        throw new NullPointerException();
    if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
        throw new IllegalArgumentException("not owner");
    return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
}
// 获取同一个Condition类的等待线程
protected Collection<Thread> getWaitingThreads(Condition condition) {
    if (condition == null)
        throw new NullPointerException();
    if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
        throw new IllegalArgumentException("not owner");
    return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
}

从ReentrantLock的方法上可以看出所有的锁操作都是基于Sync的实例完成。

ReentrantLock 的 Sync 抽象类

abstract static class Sync extends AbstractQueuedSynchronizer

Sync 抽象类继承AQS

ReentrantLock 的 Sync 方法

// 重入锁
abstract void lock();
// 获取锁(非公平)
final boolean nonfairTryAcquire(int acquires) {
    // 获取当前线程
    final Thread current = Thread.currentThread();
    // 获取锁状态
    int c = getState();
    // 没有线程持有锁
    if (c == 0) {
        // 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");
        // 修改计数个数(状态加1)
        // 持有锁的就是当前线程所以可以直接修改
        setState(nextc);
        return true;
    }
    // 返回获取失败
    return false;
}
// 释放锁
protected final boolean tryRelease(int releases) {
    // 计算计数个数
    int c = getState() - releases;
    // 持有锁的线程是否为当前线程
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    // 是否完全释放锁标志
    boolean free = false;
    // 计数器已经为0,置空持有锁的线程
    if (c == 0) {
        free = true;
        setExclusiveOwnerThread(null);
    }
    // 修改计数器
    setState(c);
    // 返回最终结果
    return free;
}
// 持有锁的线程是否为当前线程
protected final boolean isHeldExclusively() {
    return getExclusiveOwnerThread() == Thread.currentThread();
}
// 创建条件
final AbstractQueuedSynchronizer.ConditionObject newCondition() {
    return new AbstractQueuedSynchronizer.ConditionObject();
}
// 获取持有锁的线程
final Thread getOwner() {
    return getState() == 0 ? null : getExclusiveOwnerThread();
}
// 获取锁计数个数
final int getHoldCount() {
    return isHeldExclusively() ? getState() : 0;
}
// 是否锁定
final boolean isLocked() {
    return getState() != 0;
}
// 序列化
private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
    s.defaultReadObject();
    setState(0); 
}

ReentrantLock 中Sync 抽象类有两个实现类,NonfairSync非公平锁和FairSync公平锁

ReentrantLock 中FairSync 类

static final class FairSync extends ReentrantLock.Sync

ReentrantLock 中FairSync 构造函数

FairSync() {
}

ReentrantLock 中FairSync 方法

// 重入锁
final void lock() {
    // 调用AQS中acquire
    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()) {
        // 计数个数加1
        int nextc = c + acquires;
        if (nextc < 0)
            throw new Error("Maximum lock count exceeded");
        setState(nextc);
        // 返回获取锁成功
        return true;
    }
    // 返回获取锁失败
    return false;
}

ReentrantLock 中NonfairSync 类

static final class NonfairSync extends Sync

ReentrantLock 中NonfairSync 的方法

// 重入锁
final void lock() {
    // 先获取一次锁,获取成功修改锁持有者
    if (compareAndSetState(0, 1))
        setExclusiveOwnerThread(Thread.currentThread());
    // 没有获取到锁就去排队
    else
        acquire(1);
}
// 获取锁并返回结果
protected final boolean tryAcquire(int acquires) {
    return nonfairTryAcquire(acquires);
}

ReentrantLock是平时最常用的锁,正常情况下使用非公平锁。ReentrantLock类大部分人都能看懂,从源码中可以看出它并没有定义state属性、exclusiveOwnerThread属性、acquire方法等,这些其实都是使用AQS的。

posted @ 2020-05-25 14:43  源码猎人  阅读(161)  评论(0)    收藏  举报