AbstractQueuedSynchronizer源码详解

AbstractQueuedSynchronizer 源码详解

AbstractQueuedSynchronizer 简述

AbstractQueuedSynchronizerjucjava.util.concurrent)包下的一个线程相关类,主要功能是作为同步队列器,后面简称为AQS

AQS被多个线程类所使用,包括重入锁(ReentrantLock),读写重入锁(ReentrantReadWriteLock),信号量(Semaphore),计数器(CountDownLatch)等,这几种都是内部拥有对象属性Sync,静态抽象类Sync继承了AQS;线程池(ThreadPoolExecutor)中的私有内部类(Worker,即线程任务,实现了Runnable)也是继承了AQS

本篇文章将以重入锁(ReentrantLock)为切入点,并通过解析ReentrantLock中最基础的lock()unlock()方法,来深入分析AQS的源码;

源码分析

分析准备

在分析前需要以重入锁为基础,实现一个简单的Demo类;

public class Demo {
    public static void main(String[] args) {
        ReentrantLock reentrantLock = new ReentrantLock();
        Runnable runnable = () -> {
            // 上锁
            reentrantLock.lock();
            for (int i = 0; i < 10000; i++) {
                System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
            }
            // 解锁
            reentrantLock.unlock();
        };
        // 启动两个线程
        new Thread(runnable, "thread-test-1").start();
        new Thread(runnable, "thread-test-2").start();
    }
}

执行代码,会发现线程2会等待线程1执行完毕后再继续执行,执行结果不做展示;

初始化 ReentrantLock

当创建一个ReentrantLock对象时,其内部实际创建的是非公平锁对象(这里采用的是默认的构造方法);

// sync是ReentrantLock的内部类,并作为ReentrantLock的私有属性存在
private final Sync sync;

// 默认false, 使用非公平锁
public ReentrantLock() {
    sync = new NonfairSync();
}

// true 公平锁,false 非公平锁
public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}

Sync也是继承了AbstractQueuedSynchronizer

abstract static class Sync extends AbstractQueuedSynchronizer {...}

当顺着构造方法向上追溯,会发现实际上执行的是AQS的构造方法;

protected AbstractQueuedSynchronizer() { }

ReentrantLock 的 lock() 方法

ReentrantLocklock()方法即为上锁操作;方法内部调用了Synclock()方法;

public void lock() {
    sync.lock();
}

进入非公平锁的lock()方法;

final void lock() {
    // cas重入判断
    if (compareAndSetState(0, 1))
        setExclusiveOwnerThread(Thread.currentThread());
    else
        acquire(1);
}
Sync 的 lock() 方法

Synclock()方法,会执行AQS中定义的compareAndSetState()方法,首先会进行CAS(比较替换)重入判断;传入一个期待值0,若内存中的值等于0,则将内存中的值更新为1,并返回true,更新失败则为false

protected final boolean compareAndSetState(int expect, int update) {
    // 执行了Unsafe类中的compareAndSwapInt()方法
    return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}

compareAndSetState()方法内部执行了Unsafe类中的compareAndSwapInt()方法,compareAndSwapInt()方法是一个native方法,因此是原子性的;

注意,compareAndSwapInt()方法也是实现CAS的最常用方法;

compareAndSetState()方法更新成功,则表示可重入,否则表示当前已有其他线程抢占了锁资源,将执行acquire()方法,进入等待重试逻辑;

方法中的stateOffset值为state属性在内存中的偏移量,即可理解为state属性在内存中的存储位置,AQS使用静态代码块的方式,已初始化了一系列属性的内存偏移值;

private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long stateOffset;
private static final long headOffset;
private static final long tailOffset;
private static final long waitStatusOffset;
private static final long nextOffset;

static {
    try {
        stateOffset = unsafe.objectFieldOffset
            (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
        headOffset = unsafe.objectFieldOffset
            (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
        tailOffset = unsafe.objectFieldOffset
            (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
        waitStatusOffset = unsafe.objectFieldOffset
            (Node.class.getDeclaredField("waitStatus"));
        nextOffset = unsafe.objectFieldOffset
            (Node.class.getDeclaredField("next"));

    } catch (Exception ex) { throw new Error(ex); }
}

首先,当线程A执行到lock()方法时,此时无线程竞争锁,因此compareAndSetState()方法成功替换state属性值为1(初始化AQS时,stats属性默认赋值为0),返回true

private volatile int state;

state属性由volatile关键字修饰,因此对其他线程可见;

此时CAS操作完成,将执行setExclusiveOwnerThread()方法,传入当前线程对象Thread.currentThread()

protected final void setExclusiveOwnerThread(Thread thread) {
    exclusiveOwnerThread = thread;
}

此时,对AQS中属性exclusiveOwnerThread赋值为当前线程对象,此属性标识了当前独占的线程对象;

AQS 的 acquire() 方法

此时,若有线程B也执行到了lock()方法,同样首先进行了CAS操作,但因为当前已有线程A先抢占了锁(此时state属性值为1),因此CAS操作失败,将执行acquire()方法,传入参数1

public final void acquire(int arg) {
    if (!tryAcquire(arg) &&
        acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
        selfInterrupt();
}

acquire()方法会进行重试判断操作;

AQS 的 tryAcquire() 方法

首先,将执行tryAcquire()方法,tryAcquire()方法在NonfairSync类中被重写(FairSync重写逻辑不做详解);

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

内部执行了Sync中的nonfairTryAcquire()方法;

final boolean nonfairTryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    // 获取状态
    int c = getState();
    if (c == 0) {
        if (compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    }
    // 判断你是否是同一个线程对象(重入概念)
    else if (current == getExclusiveOwnerThread()) {
        int nextc = c + acquires;
        if (nextc < 0) // overflow
            throw new Error("Maximum lock count exceeded");
        setState(nextc);
        return true;
    }
    return false;
}

首先,会进行判断state属性值是否为0,即锁资源已释放(state会在执行unlock()方式时,重置为0),这里主要是对一些线程任务逻辑处理很快的情况进行判断,进行再次CAS重试,防止在线程B正在进行判断的同时,线程A已释放锁的情况,避免一些不必要的判断,可以更快的获取锁资源;若此时,CAS成功,将线程B设置为独占线程;

state不为0,那么将判断当前线程是否与独占线程属性是同一个线程对象,若是则返回true,并将state状态加1,记录重入次数,这里主要是锁重入机制的展现;

因为据统计,大部分情况下,程序执行的线程都只有一个线程,而获取释放锁的操作是重量级的,极耗性能,因此这里判断,若是同一个线程,就直接放行,此时就相当于无锁状态;

若上述判断都不成立,则表示,存在锁竞争的情况,将继续执行判断acquireQueued()方法;

首先会执行addWaiter(Node.EXCLUSIVE)方法;

在解释addWaiter()方法之前需要先详细描述一下AQS中最关键的内部类Node,这也是AQS同步队列中的基础;

线程节点 Node 类

Node中封装了当前线程对象,并与其他Node对象组成了一个双向链表,这也就是AQS中同步队列的含义;

Node中比较关键的属性表示线程节点的等待状态,主要拥有五种状态;

  1. CANCELLED(1),表示当前节点已取消调度;当timeout线程超时或被中断(响应中断的情况下),会触发变更为此状态,进入该状态后的节点将不会再变化;
  2. SIGNAL(-1),表示后继节点在等待当前节点唤醒;后继节点入队时,会将前继节点的状态更新为SIGNAL
  3. CONDITION(-2),表示节点等待在Condition上,当其他线程调用了Conditionsignal()方法后,CONDITION状态的节点将从等待队列转移到同步队列中,等待获取同步锁;
  4. PROPAGATE(-3),共享模式下,前继节点不仅会唤醒其后继节点,同时也可能会唤醒后继的后继节点;
  5. 0,新节点入队时的默认状态;

AQS中,也通过标识了头尾Node节点,来确定Node双向链表的顺序;节点headtail通过修饰volatile,对所有线程可见;

注,修饰符transient表示当前属性不会被序列化;

private transient volatile Node head;
private transient volatile Node tail;

Node节点的详细源码,请查看附录源码中的线程节点Node章节;

AQS 的 addWaiter() 方法

紧接上文,继续分析addWaiter()方法;

// Node中的属性和构造方法
static final Node EXCLUSIVE = null;
Node nextWaiter;

Node(Thread thread, Node mode) {     // Used by addWaiter
    this.nextWaiter = mode;
    this.thread = thread;
}
private Node addWaiter(Node mode) {
    Node node = new Node(Thread.currentThread(), mode);
    Node pred = tail;
    if (pred != null) {
        node.prev = pred;
        if (compareAndSetTail(pred, node)) {
            pred.next = node;
            return node;
        }
    }
    enq(node);
    return node;
}

这里会将当前线程封装为一个Node节点,并设置属性thread为当前线程,前置节点prev指向AQS中的尾部节点tail

AQS中的尾部节点tail为空,说明同步队列还初始化,则执行enq()方法;否则将Node节点前置节点prev指向尾节点;之后执行compareAndSetTail()方法,更新tail属性指向当前节点;

private final boolean compareAndSetTail(Node expect, Node update) {
    return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
}

compareAndSetTail()同样是CAS操作,将tail指向当前Node节点(原子性更新操作,防止多个线程同时操作tail属性),若成功,则表示向同步队列的尾部插入Node节点成功,否则将继续执行enq()方法;

AQS 的 enq() 方法

AQS中的enq()方法是个核心方法,主要处理了同步队列的初始化,以及向尾部添加节点的操作;

private Node enq(final Node node) {
    for (;;) {
        Node t = tail;
        if (t == null) { // Must initialize
            if (compareAndSetHead(new Node()))
                tail = head;
        } else {
            node.prev = t;
            if (compareAndSetTail(t, node)) {
                t.next = node;
                return t;
            }
        }
    }
}

这里,enq()方法采用了自旋的方式,尝试向同步队列中添加节点;这里主要分为两种情形;

一,同步队列未初始化;此时,tail为空,这里会通过new Node()初始化一个头节点,注意,这里初始化的Node节点是一个空节点,未指定任何属性变量AQS中的headtail同时指向这个空节点;

之后会再次自旋,将当前传入的Node节点的前置节点指向刚刚初始化的空节点,并再次CAS,将tail替换为当前Node,并将head节点的下个节点next指向当前Node

二,同步队列已初始化;此时,会获取节点tail,并将当前节点的前置节点prev指向尾部节点,CAS操作替换tail为当前Node,并将prevnext节点指向当前Node

当上述操作完成后,则表示当前Node已成功插入,否则将继续自旋,直到插入完成;

AQS 的 acquireQueued() 方法

addWaiter()执行成功,将继续执行判断方法acquireQueued()

final boolean acquireQueued(final Node node, int arg) {
    // 取消标志
    boolean failed = true;
    try {
        // 中断标志
        boolean interrupted = false;
        for (;;) {
            final Node p = node.predecessor();
            if (p == head && tryAcquire(arg)) {
                setHead(node);
                p.next = null; // help GC
                failed = false;
                return interrupted;
            }
            if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())
                interrupted = true;
        }
    } finally {
        if (failed)
            // 这里是一个对标记为取消的节点的操作,lock()方法中未涉及,这里不作详解
            cancelAcquire(node);
    }
}
// Node中的
final Node predecessor() throws NullPointerException {
    Node p = prev;
    if (p == null)
        throw new NullPointerException();
    else
        return p;
}

这里同样采用自旋的方式,首先调用了Node类中的predecessor()predecessor()方法用于获取当前节点Node的前置节点prev

之后继续判断前置节点prev是否指向head节点,如果是head节点,则表示当前节点为同步队列中的第二个节点,此时便拥有资格去竞争锁资源(可能是head节点释放完资源唤醒当前节点,当然也可能是headinterrupt了),则再次调用tryAcquire()方法,尝试去获取锁(即当前线程会去尝试CAS操作state状态更新为1,或者判断是否是重入状态);

若成功,则竞争锁成功,将当前Node设置为head节点,并将原head节点的next设置为null,此处是为了帮助GC,防止过多的原head在内存中占用资源;

若抢占未成功,将执行后续判断,首先执行shouldParkAfterFailedAcquire()方法;

private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
    int ws = pred.waitStatus;
    if (ws == Node.SIGNAL) // Node.SIGNAL = -1
        return true;
    if (ws > 0) {
        do {
            node.prev = pred = pred.prev;
        } while (pred.waitStatus > 0);
        pred.next = node;
    } else {
        compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
    }
    return false;
}

private static final boolean compareAndSetWaitStatus(Node node, int expect, int update){
    return unsafe.compareAndSwapInt(node, waitStatusOffset, expect, update);
}

shouldParkAfterFailedAcquire()主要是判断当前节点的前置节点的状态waitStatus

Node.SIGNAL = -1表示后续节点在等待当前节点唤醒,直接则返回true,表示当前节点在等待前置节点唤醒;

waitStatus > 0,主要指的是CANCELLED = 1状态,表示当前Node取消了调度,因此当前Nodeprev属性向前寻找前置Node,直到向前找到waitStatus不再是取消状态的Node,并做双向关联,将已取消的节点从链表中去除,重新形成新的Node链表;

若前置节点Nodeprev0,-2,-3时(waitStatus-2,-3在当前普通的lock()方法中未涉及到),则会将前置节点的状态变更为-1

因此在lock()方法中,同步队列最终所有的节点的waitStatus都将被设置为-1

shouldParkAfterFailedAcquire()返回true,将继续执行parkAndCheckInterrupt()

private final boolean parkAndCheckInterrupt() {
    LockSupport.park(this);
    return Thread.interrupted();
}

parkAndCheckInterrupt()可以看到,到这一步时,当前会pack()当前线程,线程进入休眠,此时,等待unlock()方法将线程唤醒;

公平锁FairSync与非公平锁NonfairSync的区别

经过上述对ReentrantLock的加锁逻辑进行了剖析,可以看出,非公平锁NonfairSync在进入同步队列前会进行多次cas重入判断,即竞争锁的动作,只有当这几次竞争均失败后,才会进入同步队列等待,之后按顺序获取锁资源,即新加入的线程会与同步队列中头部Node线程竞争锁资源(排除掉head哨兵空节点),同步队列中线程Node按顺序依次获取竞争锁资源的资格;

公平锁FairSync则是直接进入同步队列,不参与竞争锁资源的操作,按队列顺序获取锁资源;

ReentrantLock 的 unlock() 方法

AQS 的 release() 方法

ReentrantLock中的释放锁方法unlock(),内部是直接执行了AQS中的release()方法;

public void unlock() {
    sync.release(1);
}
// AQS中定义的方法
public final boolean release(int arg) {
    if (tryRelease(arg)) {
        Node h = head;
        if (h != null && h.waitStatus != 0)
            unparkSuccessor(h);
        return true;
    }
    return false;
}
Sync 的 tryRelease() 方法

首先,执行了tryRelease()方法,tryRelease()Sync中被重写;

// Sync中重写了tryRelease()
protected final boolean tryRelease(int releases) {
    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;
}

可以看到参数releases传入的值为1AQSstate属性会进行减一的操作,并会校验当前线程是否与AQS的当前的独占线程是同一线程;

state减一之后值为0,则表示当前线程已执行完毕,将释放锁资源,并将AQS的独占线程标识重置为null,state重置为0,此时表示当前没有加锁,后续被唤醒的线程节点,以及正在执行lock()方法还没进入队列的线程可以竞争锁资源;

注意,之前说过重入锁的机制,若同一线程连续的加锁,将不会阻塞当前线程的执行,而是将state进行加一操作,因此,若对同一锁多次执行lock()方法,就需要同样数量的unlock()来释放锁,否则将会产生死锁

那么,最开始的Demo方法进行改造,即为;

public static void main(String[] args) {
    ReentrantLock reentrantLock = new ReentrantLock();
    Runnable runnable = () -> {
        // 上锁
        try {
            reentrantLock.lock();
            System.out.println("加了第一遍锁!");
            reentrantLock.lock();
            System.out.println("加了第二遍锁!");
            for (int i = 0; i < 100; i++) {
                System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
            }
        } finally {
            // 解锁,需要与lock()方法数量一致
            reentrantLock.unlock();
            reentrantLock.unlock();
        }
    };
    // 启动两个线程
    new Thread(runnable, "thread-test-1").start();
    new Thread(runnable, "thread-test-2").start();
}

若对同一锁的unlock()数量少于lock(),则会发生死锁,若多于,则会报非法监视器状态异常IllegalMonitorStateException

如果去查看jvm底层源码,就会发现jvm在创建每一个对象时都会生成一个对象监视器monitor,这也是为什么所有对象都可以作为锁对象,并且这也就是为什么wait()notify()等线程相关的方法会定义在Object中,所有对象都可以调用的原因;

AQS 的 unparkSuccessor() 方法

tryRelease()方法执行成功,则会获取head节点,并判断head节点的waitStatus不为空,若判断为true,则执行unparkSuccessor()方法;

private void unparkSuccessor(Node node) {
    int ws = node.waitStatus;
    if (ws < 0)
        compareAndSetWaitStatus(node, ws, 0);
    Node s = node.next;
    if (s == null || s.waitStatus > 0) {
        s = null;
        for (Node t = tail; t != null && t != node; t = t.prev)
            if (t.waitStatus <= 0)
                s = t;
    }
    if (s != null)
        LockSupport.unpark(s.thread);
}

unparkSuccessor()方法的作用主要是为了将后继节点唤醒,会将head节点作为参数传入;

首先会判断是否head节点的waitStatus < 0(即-1,-2,-3,状态为-1表示取消,之前已经被从队列中去除了),若是则将waitStatus更新为初始状态0;之后会获取head的后继节点,即队列的第二个节点;

若后继节点为空或者后继节点的状态大于0,即取消状态,则会从队列的尾部tail(当headtail指向同一个节点,即队列中只有一个节点时,不会进入循环)向前遍历,排除waitStatus为取消状态的节点,直到遍历到head节点前,即找到队列第二个节点;

之后,若后继节点不为空,则执行LockSupport.unpark()方法,唤醒后继节点中的线程,此时后继节点开始竞争锁资源,后继节点会从之前acquireQueued()方法中被park()处继续执行自旋,尝试获取锁资源,若获取成功则将后继节点设置为head,否则,将再次被park(),等待下一次被唤醒;

至此,完整的加锁解锁逻辑已经逐步分析完毕;AQS中还有内部类ConditionObject,内部维护了AQS的等待队列,具体的实现原理不再在这里赘述,可以自行查看源码,其大致原理相似;

所以,今天的AQS源码,你学会了吗?

附录 源码

ReentrantLock 源码总览

下面展示出了ReentrantLock的全部源码;

重入锁 ReentrantLock

ReentrantLock内部定义了Sync对象属性,Sync是一个抽象类,拥有两个实现,非公平锁NonfairSync和公平锁FairSyncReentrantLock默认使用的是非公平锁,可以通过在构造方法中传递布尔值,指定ReentrantLock使用的锁类型;

public class ReentrantLock implements Lock, java.io.Serializable {
    private static final long serialVersionUID = 7373984872572414699L;
    
    private final Sync sync;

    // 默认false, 使用非公平锁
    public ReentrantLock() {
        sync = new NonfairSync();
    }

    // true 公平锁,false 非公平锁
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

    // 加锁方法
    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();
    }

    public final boolean isFair() {
        return sync instanceof FairSync;
    }

    protected Thread getOwner() {
        return sync.getOwner();
    }

    public final boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }

    public final boolean hasQueuedThread(Thread thread) {
        return sync.isQueued(thread);
    }

    public final int getQueueLength() {
        return sync.getQueueLength();
    }

    protected Collection<Thread> getQueuedThreads() {
        return sync.getQueuedThreads();
    }

    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);
    }

    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);
    }

    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);
    }
}
抽象同步锁类 Sync

抽象类SyncReentrantLock中定义的内部类,并作为ReentrantLock的私有属性存在;Sync有两个实现,非公平锁NonfairSync和公平锁FairSync

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

    abstract void lock();

    final boolean nonfairTryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        if (c == 0) {
            if (compareAndSetState(0, acquires)) {
                setExclusiveOwnerThread(current);
                return true;
            }
        }
        else if (current == getExclusiveOwnerThread()) {
            int nextc = c + acquires;
            if (nextc < 0) // overflow
                throw new Error("Maximum lock count exceeded");
            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;
        if (c == 0) {
            free = true;
            setExclusiveOwnerThread(null);
        }
        setState(c);
        return free;
    }

    protected final boolean isHeldExclusively() {
        return getExclusiveOwnerThread() == Thread.currentThread();
    }

    final ConditionObject newCondition() {
        return new 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); // reset to unlocked state
    }
}
Sync 锁实现

非公平锁NonfairSync和公平锁FairSyncReentrantLock中的静态内部类,分别实现了Sync中的lock()AQS中的tryAcquire()方法;

非公平锁 NonfairSync
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);
    }
}
公平锁 FairSync
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;
    }
}

AbstractQueuedSynchronizer 源码总览

下面先简单AQS源码进行展示;

队列同步器 AbstractQueuedSynchronizer
public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {

    private static final long serialVersionUID = 7373984972572414691L;

    protected AbstractQueuedSynchronizer() { }

    private transient volatile Node head;

    private transient volatile Node tail;

    private volatile int state;

    protected final int getState() {
        return state;
    }

    protected final void setState(int newState) {
        state = newState;
    }

    protected final boolean compareAndSetState(int expect, int update) {
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

    static final long spinForTimeoutThreshold = 1000L;

    private Node enq(final Node node) {
        for (;;) {
            Node t = tail;
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }

    private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        Node pred = tail;
        if (pred != null) {
            node.prev = pred;
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        enq(node);
        return node;
    }

    private void setHead(Node node) {
        head = node;
        node.thread = null;
        node.prev = null;
    }

    private void unparkSuccessor(Node node) {
        int ws = node.waitStatus;
        if (ws < 0)
            compareAndSetWaitStatus(node, ws, 0);
        Node s = node.next;
        if (s == null || s.waitStatus > 0) {
            s = null;
            for (Node t = tail; t != null && t != node; t = t.prev)
                if (t.waitStatus <= 0)
                    s = t;
        }
        if (s != null)
            LockSupport.unpark(s.thread);
    }

    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;            // loop to recheck cases
                    unparkSuccessor(h);
                }
                else if (ws == 0 &&
                         !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
                    continue;                // loop on failed CAS
            }
            if (h == head)                   // loop if head changed
                break;
        }
    }

    private void setHeadAndPropagate(Node node, int propagate) {
        Node h = head; // Record old head for check below
        setHead(node);
        if (propagate > 0 || h == null || h.waitStatus < 0 ||
            (h = head) == null || h.waitStatus < 0) {
            Node s = node.next;
            if (s == null || s.isShared())
                doReleaseShared();
        }
    }

    private void cancelAcquire(Node node) {
        if (node == null)
            return;

        node.thread = null;

        Node pred = node.prev;
        while (pred.waitStatus > 0)
            node.prev = pred = pred.prev;
        
        Node predNext = pred.next;
        node.waitStatus = Node.CANCELLED;

        if (node == tail && compareAndSetTail(node, pred)) {
            compareAndSetNext(pred, predNext, null);
        } else {
            int ws;
            if (pred != head &&
                ((ws = pred.waitStatus) == Node.SIGNAL ||
                 (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
                pred.thread != null) {
                Node next = node.next;
                if (next != null && next.waitStatus <= 0)
                    compareAndSetNext(pred, predNext, next);
            } else {
                unparkSuccessor(node);
            }

            node.next = node; // help GC
        }
    }

    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
        int ws = pred.waitStatus;
        if (ws == Node.SIGNAL)
            return true;
        if (ws > 0) {
            do {
                node.prev = pred = pred.prev;
            } while (pred.waitStatus > 0);
            pred.next = node;
        } else {
            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
        }
        return false;
    }

    static void selfInterrupt() {
        Thread.currentThread().interrupt();
    }

    private final boolean parkAndCheckInterrupt() {
        LockSupport.park(this);
        return Thread.interrupted();
    }

    final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    private void doAcquireInterruptibly(int arg)
        throws InterruptedException {
        final Node node = addWaiter(Node.EXCLUSIVE);
        boolean failed = true;
        try {
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    private boolean doAcquireNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (nanosTimeout <= 0L)
            return false;
        final long deadline = System.nanoTime() + nanosTimeout;
        final Node node = addWaiter(Node.EXCLUSIVE);
        boolean failed = true;
        try {
            for (;;) {
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return true;
                }
                nanosTimeout = deadline - System.nanoTime();
                if (nanosTimeout <= 0L)
                    return false;
                if (shouldParkAfterFailedAcquire(p, node) &&
                    nanosTimeout > spinForTimeoutThreshold)
                    LockSupport.parkNanos(this, nanosTimeout);
                if (Thread.interrupted())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    private void doAcquireShared(int arg) {
        final Node node = addWaiter(Node.SHARED);
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                if (p == head) {
                    int r = tryAcquireShared(arg);
                    if (r >= 0) {
                        setHeadAndPropagate(node, r);
                        p.next = null; // help GC
                        if (interrupted)
                            selfInterrupt();
                        failed = false;
                        return;
                    }
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    private void doAcquireSharedInterruptibly(int arg)
        throws InterruptedException {
        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);
        }
    }

    private boolean doAcquireSharedNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (nanosTimeout <= 0L)
            return false;
        final long deadline = System.nanoTime() + nanosTimeout;
        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 true;
                    }
                }
                nanosTimeout = deadline - System.nanoTime();
                if (nanosTimeout <= 0L)
                    return false;
                if (shouldParkAfterFailedAcquire(p, node) &&
                    nanosTimeout > spinForTimeoutThreshold)
                    LockSupport.parkNanos(this, nanosTimeout);
                if (Thread.interrupted())
                    throw new InterruptedException();
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }

    protected boolean tryRelease(int arg) {
        throw new UnsupportedOperationException();
    }

    protected int tryAcquireShared(int arg) {
        throw new UnsupportedOperationException();
    }

    protected boolean tryReleaseShared(int arg) {
        throw new UnsupportedOperationException();
    }

    protected boolean isHeldExclusively() {
        throw new UnsupportedOperationException();
    }

    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

    public final void acquireInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        if (!tryAcquire(arg))
            doAcquireInterruptibly(arg);
    }

    public final boolean tryAcquireNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        return tryAcquire(arg) ||
            doAcquireNanos(arg, nanosTimeout);
    }

    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 void acquireShared(int arg) {
        if (tryAcquireShared(arg) < 0)
            doAcquireShared(arg);
    }

    public final void acquireSharedInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        if (tryAcquireShared(arg) < 0)
            doAcquireSharedInterruptibly(arg);
    }

    public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        return tryAcquireShared(arg) >= 0 ||
            doAcquireSharedNanos(arg, nanosTimeout);
    }

    public final boolean releaseShared(int arg) {
        if (tryReleaseShared(arg)) {
            doReleaseShared();
            return true;
        }
        return false;
    }

    public final boolean hasQueuedThreads() {
        return head != tail;
    }

    public final boolean hasContended() {
        return head != null;
    }

    public final Thread getFirstQueuedThread() {
        return (head == tail) ? null : fullGetFirstQueuedThread();
    }

    private Thread fullGetFirstQueuedThread() {
        Node h, s;
        Thread st;
        if (((h = head) != null && (s = h.next) != null &&
             s.prev == head && (st = s.thread) != null) ||
            ((h = head) != null && (s = h.next) != null &&
             s.prev == head && (st = s.thread) != null))
            return st;

        Node t = tail;
        Thread firstThread = null;
        while (t != null && t != head) {
            Thread tt = t.thread;
            if (tt != null)
                firstThread = tt;
            t = t.prev;
        }
        return firstThread;
    }

    public final boolean isQueued(Thread thread) {
        if (thread == null)
            throw new NullPointerException();
        for (Node p = tail; p != null; p = p.prev)
            if (p.thread == thread)
                return true;
        return false;
    }

    final boolean apparentlyFirstQueuedIsExclusive() {
        Node h, s;
        return (h = head) != null &&
            (s = h.next)  != null &&
            !s.isShared()         &&
            s.thread != null;
    }

    public final boolean hasQueuedPredecessors() {
        Node t = tail; // Read fields in reverse initialization order
        Node h = head;
        Node s;
        return h != t &&
            ((s = h.next) == null || s.thread != Thread.currentThread());
    }

    public final int getQueueLength() {
        int n = 0;
        for (Node p = tail; p != null; p = p.prev) {
            if (p.thread != null)
                ++n;
        }
        return n;
    }

    public final Collection<Thread> getQueuedThreads() {
        ArrayList<Thread> list = new ArrayList<Thread>();
        for (Node p = tail; p != null; p = p.prev) {
            Thread t = p.thread;
            if (t != null)
                list.add(t);
        }
        return list;
    }

    public final Collection<Thread> getExclusiveQueuedThreads() {
        ArrayList<Thread> list = new ArrayList<Thread>();
        for (Node p = tail; p != null; p = p.prev) {
            if (!p.isShared()) {
                Thread t = p.thread;
                if (t != null)
                    list.add(t);
            }
        }
        return list;
    }

    public final Collection<Thread> getSharedQueuedThreads() {
        ArrayList<Thread> list = new ArrayList<Thread>();
        for (Node p = tail; p != null; p = p.prev) {
            if (p.isShared()) {
                Thread t = p.thread;
                if (t != null)
                    list.add(t);
            }
        }
        return list;
    }

    public String toString() {
        int s = getState();
        String q  = hasQueuedThreads() ? "non" : "";
        return super.toString() +
            "[State = " + s + ", " + q + "empty queue]";
    }

    final boolean isOnSyncQueue(Node node) {
        if (node.waitStatus == Node.CONDITION || node.prev == null)
            return false;
        if (node.next != null) // If has successor, it must be on queue
            return true;
        return findNodeFromTail(node);
    }

    private boolean findNodeFromTail(Node node) {
        Node t = tail;
        for (;;) {
            if (t == node)
                return true;
            if (t == null)
                return false;
            t = t.prev;
        }
    }

    final boolean transferForSignal(Node node) {
        if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
            return false;
        Node p = enq(node);
        int ws = p.waitStatus;
        if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
            LockSupport.unpark(node.thread);
        return true;
    }

    final boolean transferAfterCancelledWait(Node node) {
        if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
            enq(node);
            return true;
        }

        while (!isOnSyncQueue(node))
            Thread.yield();
        return false;
    }

    final int fullyRelease(Node node) {
        boolean failed = true;
        try {
            int savedState = getState();
            if (release(savedState)) {
                failed = false;
                return savedState;
            } else {
                throw new IllegalMonitorStateException();
            }
        } finally {
            if (failed)
                node.waitStatus = Node.CANCELLED;
        }
    }

    public final boolean owns(ConditionObject condition) {
        return condition.isOwnedBy(this);
    }

    public final boolean hasWaiters(ConditionObject condition) {
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.hasWaiters();
    }

    public final int getWaitQueueLength(ConditionObject condition) {
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.getWaitQueueLength();
    }

    public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.getWaitingThreads();
    }

	// 初始赋值了一系列内存偏移量
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long stateOffset;
    private static final long headOffset;
    private static final long tailOffset;
    private static final long waitStatusOffset;
    private static final long nextOffset;

    static {
        try {
            stateOffset = unsafe.objectFieldOffset
                (AbstractQueuedSynchronizer.class.getDeclaredField("state"));
            headOffset = unsafe.objectFieldOffset
                (AbstractQueuedSynchronizer.class.getDeclaredField("head"));
            tailOffset = unsafe.objectFieldOffset
                (AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
            waitStatusOffset = unsafe.objectFieldOffset
                (Node.class.getDeclaredField("waitStatus"));
            nextOffset = unsafe.objectFieldOffset
                (Node.class.getDeclaredField("next"));

        } catch (Exception ex) { throw new Error(ex); }
    }

    private final boolean compareAndSetHead(Node update) {
        return unsafe.compareAndSwapObject(this, headOffset, null, update);
    }

    private final boolean compareAndSetTail(Node expect, Node update) {
        return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
    }

    private static final boolean compareAndSetWaitStatus(
        Node node, int expect, int update) {
        return unsafe.compareAndSwapInt(node, waitStatusOffset,expect, update);
    }

    private static final boolean compareAndSetNext(
        Node node, Node expect, Node update) {
        return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
    }
}
线程节点 Node

Node类是AQS中的静态内部类,也是AQS中最为关键的类;

static final class Node {
    // 共享
    static final Node SHARED = new Node();
    // 独占
    static final Node EXCLUSIVE = null;
    static final int CANCELLED =  1;
    static final int SIGNAL    = -1;
    static final int CONDITION = -2;
    static final int PROPAGATE = -3;
	
    volatile int waitStatus;
    volatile Node prev;
    volatile Node next;
    volatile Thread thread;
    Node nextWaiter;

    final boolean isShared() {
        return nextWaiter == SHARED;
    }

    final Node predecessor() throws NullPointerException {
        Node p = prev;
        if (p == null)
            throw new NullPointerException();
        else
            return p;
    }

    Node() {    // Used to establish initial head or SHARED marker
    }

    Node(Thread thread, Node mode) {     // Used by addWaiter
        this.nextWaiter = mode;
        this.thread = thread;
    }

    Node(Thread thread, int waitStatus) { // Used by Condition
        this.waitStatus = waitStatus;
        this.thread = thread;
    }
}
ConditionObject类

ConditionObjectAQS中的内部类,主要是为并发编程中的同步提供了等待通知的实现方式,可以在不满足某个条件的时候挂起线程等待,直到满足某个条件的时候在唤醒线程;

public class ConditionObject implements Condition, java.io.Serializable {
    private static final long serialVersionUID = 1173984872572414699L;
    
    private transient Node firstWaiter;
    
    private transient Node lastWaiter;

    public ConditionObject() { }

    private Node addConditionWaiter() {
        Node t = lastWaiter;
        if (t != null && t.waitStatus != Node.CONDITION) {
            unlinkCancelledWaiters();
            t = lastWaiter;
        }
        Node node = new Node(Thread.currentThread(), Node.CONDITION);
        if (t == null)
            firstWaiter = node;
        else
            t.nextWaiter = node;
        lastWaiter = node;
        return node;
    }

    private void doSignal(Node first) {
        do {
            if ( (firstWaiter = first.nextWaiter) == null)
                lastWaiter = null;
            first.nextWaiter = null;
        } while (!transferForSignal(first) &&
                 (first = firstWaiter) != null);
    }

    private void doSignalAll(Node first) {
        lastWaiter = firstWaiter = null;
        do {
            Node next = first.nextWaiter;
            first.nextWaiter = null;
            transferForSignal(first);
            first = next;
        } while (first != null);
    }

    private void unlinkCancelledWaiters() {
        Node t = firstWaiter;
        Node trail = null;
        while (t != null) {
            Node next = t.nextWaiter;
            if (t.waitStatus != Node.CONDITION) {
                t.nextWaiter = null;
                if (trail == null)
                    firstWaiter = next;
                else
                    trail.nextWaiter = next;
                if (next == null)
                    lastWaiter = trail;
            }
            else
                trail = t;
            t = next;
        }
    }

    public final void signal() {
        if (!isHeldExclusively())
            throw new IllegalMonitorStateException();
        Node first = firstWaiter;
        if (first != null)
            doSignal(first);
    }

    public final void signalAll() {
        if (!isHeldExclusively())
            throw new IllegalMonitorStateException();
        Node first = firstWaiter;
        if (first != null)
            doSignalAll(first);
    }

    public final void awaitUninterruptibly() {
        Node node = addConditionWaiter();
        int savedState = fullyRelease(node);
        boolean interrupted = false;
        while (!isOnSyncQueue(node)) {
            LockSupport.park(this);
            if (Thread.interrupted())
                interrupted = true;
        }
        if (acquireQueued(node, savedState) || interrupted)
            selfInterrupt();
    }

    private static final int REINTERRUPT =  1;

    private static final int THROW_IE    = -1;

    private int checkInterruptWhileWaiting(Node node) {
        return Thread.interrupted() ?
            (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
        0;
    }

    private void reportInterruptAfterWait(int interruptMode)
        throws InterruptedException {
        if (interruptMode == THROW_IE)
            throw new InterruptedException();
        else if (interruptMode == REINTERRUPT)
            selfInterrupt();
    }

    public final void await() throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        Node node = addConditionWaiter();
        int savedState = fullyRelease(node);
        int interruptMode = 0;
        while (!isOnSyncQueue(node)) {
            LockSupport.park(this);
            if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                break;
        }
        if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
            interruptMode = REINTERRUPT;
        if (node.nextWaiter != null) // clean up if cancelled
            unlinkCancelledWaiters();
        if (interruptMode != 0)
            reportInterruptAfterWait(interruptMode);
    }

    public final long awaitNanos(long nanosTimeout)
        throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        Node node = addConditionWaiter();
        int savedState = fullyRelease(node);
        final long deadline = System.nanoTime() + nanosTimeout;
        int interruptMode = 0;
        while (!isOnSyncQueue(node)) {
            if (nanosTimeout <= 0L) {
                transferAfterCancelledWait(node);
                break;
            }
            if (nanosTimeout >= spinForTimeoutThreshold)
                LockSupport.parkNanos(this, nanosTimeout);
            if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                break;
            nanosTimeout = deadline - System.nanoTime();
        }
        if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
            interruptMode = REINTERRUPT;
        if (node.nextWaiter != null)
            unlinkCancelledWaiters();
        if (interruptMode != 0)
            reportInterruptAfterWait(interruptMode);
        return deadline - System.nanoTime();
    }

    public final boolean awaitUntil(Date deadline)
        throws InterruptedException {
        long abstime = deadline.getTime();
        if (Thread.interrupted())
            throw new InterruptedException();
        Node node = addConditionWaiter();
        int savedState = fullyRelease(node);
        boolean timedout = false;
        int interruptMode = 0;
        while (!isOnSyncQueue(node)) {
            if (System.currentTimeMillis() > abstime) {
                timedout = transferAfterCancelledWait(node);
                break;
            }
            LockSupport.parkUntil(this, abstime);
            if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                break;
        }
        if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
            interruptMode = REINTERRUPT;
        if (node.nextWaiter != null)
            unlinkCancelledWaiters();
        if (interruptMode != 0)
            reportInterruptAfterWait(interruptMode);
        return !timedout;
    }

    public final boolean await(long time, TimeUnit unit)
        throws InterruptedException {
        long nanosTimeout = unit.toNanos(time);
        if (Thread.interrupted())
            throw new InterruptedException();
        Node node = addConditionWaiter();
        int savedState = fullyRelease(node);
        final long deadline = System.nanoTime() + nanosTimeout;
        boolean timedout = false;
        int interruptMode = 0;
        while (!isOnSyncQueue(node)) {
            if (nanosTimeout <= 0L) {
                timedout = transferAfterCancelledWait(node);
                break;
            }
            if (nanosTimeout >= spinForTimeoutThreshold)
                LockSupport.parkNanos(this, nanosTimeout);
            if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                break;
            nanosTimeout = deadline - System.nanoTime();
        }
        if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
            interruptMode = REINTERRUPT;
        if (node.nextWaiter != null)
            unlinkCancelledWaiters();
        if (interruptMode != 0)
            reportInterruptAfterWait(interruptMode);
        return !timedout;
    }

    final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
        return sync == AbstractQueuedSynchronizer.this;
    }

    protected final boolean hasWaiters() {
        if (!isHeldExclusively())
            throw new IllegalMonitorStateException();
        for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
            if (w.waitStatus == Node.CONDITION)
                return true;
        }
        return false;
    }

    protected final int getWaitQueueLength() {
        if (!isHeldExclusively())
            throw new IllegalMonitorStateException();
        int n = 0;
        for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
            if (w.waitStatus == Node.CONDITION)
                ++n;
        }
        return n;
    }

    protected final Collection<Thread> getWaitingThreads() {
        if (!isHeldExclusively())
            throw new IllegalMonitorStateException();
        ArrayList<Thread> list = new ArrayList<Thread>();
        for (Node w = firstWaiter; w != null; w = w.nextWaiter) {
            if (w.waitStatus == Node.CONDITION) {
                Thread t = w.thread;
                if (t != null)
                    list.add(t);
            }
        }
        return list;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值