Java源码——AQS源码分析

package

package java.util.concurrent.locks;

import

import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import sun.misc.Unsafe;

public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {

内部类

 static final class Node 

code

Node内部类

  static final class Node {
        /** Marker to indicate a node is waiting in shared mode */
        static final Node SHARED = new Node();
        /** Marker to indicate a node is waiting in exclusive mode */
        static final Node EXCLUSIVE = null;

        /** waitStatus value to indicate thread has cancelled */
        static final int CANCELLED =  1;
        /** waitStatus value to indicate successor's thread needs unparking */
        static final int SIGNAL    = -1;
        /** waitStatus value to indicate thread is waiting on condition */
        static final int CONDITION = -2;
        /**
         * waitStatus value to indicate the next acquireShared should
         * unconditionally propagate
         */
        static final int PROPAGATE = -3;

        /**
         * Status field, taking on only the values:
         *   SIGNAL:     The successor of this node is (or will soon be)
         *               blocked (via park), so the current node must
         *               unpark its successor when it releases or
         *               cancels. To avoid races, acquire methods must
         *               first indicate they need a signal,
         *               then retry the atomic acquire, and then,
         *               on failure, block.
         *   CANCELLED:  This node is cancelled due to timeout or interrupt.
         *               Nodes never leave this state. In particular,
         *               a thread with cancelled node never again blocks.
         *   CONDITION:  This node is currently on a condition queue.
         *               It will not be used as a sync queue node
         *               until transferred, at which time the status
         *               will be set to 0. (Use of this value here has
         *               nothing to do with the other uses of the
         *               field, but simplifies mechanics.)
         *   PROPAGATE:  A releaseShared should be propagated to other
         *               nodes. This is set (for head node only) in
         *               doReleaseShared to ensure propagation
         *               continues, even if other operations have
         *               since intervened.
         *   0:          None of the above
         *
         * The values are arranged numerically to simplify use.
         * Non-negative values mean that a node doesn't need to
         * signal. So, most code doesn't need to check for particular
         * values, just for sign.
         *
         * The field is initialized to 0 for normal sync nodes, and
         * CONDITION for condition nodes.  It is modified using CAS
         * (or when possible, unconditional volatile writes).
         */
        volatile int waitStatus;

        /**
         * Link to predecessor node that current node/thread relies on
         * for checking waitStatus. Assigned during enqueuing, and nulled
         * out (for sake of GC) only upon dequeuing.  Also, upon
         * cancellation of a predecessor, we short-circuit while
         * finding a non-cancelled one, which will always exist
         * because the head node is never cancelled: A node becomes
         * head only as a result of successful acquire. A
         * cancelled thread never succeeds in acquiring, and a thread only
         * cancels itself, not any other node.
         */
        volatile Node prev;

        /**
         * Link to the successor node that the current node/thread
         * unparks upon release. Assigned during enqueuing, adjusted
         * when bypassing cancelled predecessors, and nulled out (for
         * sake of GC) when dequeued.  The enq operation does not
         * assign next field of a predecessor until after attachment,
         * so seeing a null next field does not necessarily mean that
         * node is at end of queue. However, if a next field appears
         * to be null, we can scan prev's from the tail to
         * double-check.  The next field of cancelled nodes is set to
         * point to the node itself instead of null, to make life
         * easier for isOnSyncQueue.
         */
        volatile Node next;

        /**
         * The thread that enqueued this node.  Initialized on
         * construction and nulled out after use.
         */
        volatile Thread thread;

        /**
         * Link to next node waiting on condition, or the special
         * value SHARED.  Because condition queues are accessed only
         * when holding in exclusive mode, we just need a simple
         * linked queue to hold nodes while they are waiting on
         * conditions. They are then transferred to the queue to
         * re-acquire. And because conditions can only be exclusive,
         * we save a field by using special value to indicate shared
         * mode.
         */
        Node nextWaiter;

        /**
         * Returns true if node is waiting in shared mode.
         */
        final boolean isShared() {
            return nextWaiter == SHARED;
        }

        /**
         * Returns previous node, or throws NullPointerException if null.
         * Use when predecessor cannot be null.  The null check could
         * be elided, but is present to help the VM.
         *
         * @return the predecessor of this node
         */
        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;
        }
    }

变量

标记,用于指示一个节点在共享模式下等待
static final Node SHARED = new Node();

标记来指示节点以独占模式等待
static final Node EXCLUSIVE = null;
waitStatus值来表示线程已经取消
static final int CANCELLED =  1;

waitStatus值,指示后续线程需要释放
static final int SIGNAL    = -1;

waitStatus值,指示线程正在等待条件
static final int CONDITION = -2;

waitStatus值来表示下一个acquireShared应无条件传播
static final int PROPAGATE = -3;
对于普通同步节点,该字段初始化为0。对于ConditionNode,值为-2,如上所述。
volatile int waitStatus;

指向当前节点的前驱节点,当前节点入队时生成,出队清零。
prev不会清空,因为头结点始终存在。
volatile Node prev;

链接到当前节点/线程释放后将停放的后继节点。入队时生成,出队时取消。
volatile Node next;

入队节点对应的线程
volatile Thread thread;
链接到下一个等待条件的节点,或者特殊值SHARED。
因为条件对列只有在独占模式下才会被获取。
Node nextWaiter;

方法

如果节点在共享模式下等待,则返回truefinal 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;
        }

AQS变量

private static final long serialVersionUID = 7373984972572414691L;

等待队列的头,延迟初始化
private transient volatile Node head;

等待队列的尾部,延迟初始化。
private transient volatile Node tail;

同步状态
private volatile int state;
    

AQS方法

	AQS构造方法
	protected AbstractQueuedSynchronizer() { }
	
	返回同步状态的当前值。
 	protected final int getState() {
        return state;
    }

	设置同步状态的值。
    protected final void setState(int newState) {
        state = newState;
    }

	原子的设置同步状态的值(如果当前state值等于期望state值,则执行)
	这个CAS操作具有volatile的读-写内存语义。
	返回值:
		
    protected final boolean compareAndSetState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

队列工具

将节点插入队列,必要时进行初始化。
 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的构造,获取当前线程以及模式(SHARED,EXCLUSIVE)
        Node node = new Node(Thread.currentThread(), mode);
        // Try the fast path of enq; backup to full enq on failure
        pred 指向tail
        Node pred = tail;
        
        if (pred != null) {
        如果pred不为空,则说明我们要插入的节点的前驱节点就是pred
            node.prev = pred;
            当pred和要插入的节点node是同一个时,执行CAS操作
            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)
        如果waitStatus是负数,那么久需要将信号置位0
            compareAndSetWaitStatus(node, ws, 0);

        要实现unpark的线程被后继节点持有,但是如果节点对应的线程被取消或者为空,
        那么从tail从后向前逆序遍历,直到第一个没有被取消的节点。
        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() {
		确保一个release传播,即使有其他正在进行的acquires/releases.
		如果需要通知,他会尝试unpark头结点的后继节点。
		但如果不需要,status设置为PROPAGATE(自动传播)去确保release,传播的继续。
		此外,我们需要进入自旋来防止执行此操作时添加新的节点。
		此外,与unpark后继节点的其他用法不同,我们需要知道如果CAS重置状态失败,是否需要重新检查。
      
         自旋
        for (;;) {
            Node h = head;
            头结点不为空,也不是尾节点
            if (h != null && h != tail) {
                int ws = h.waitStatus;
                if (ws == Node.SIGNAL) {
                如果CAS操作无法执行,那么循环
                    if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
                        continue;            // loop to recheck cases
                     如果waitStatus等于-1(指示后继节点需要释放),并且CAS操作成功
                     那么unpark后继节点。
                    unparkSuccessor(h);
                }
                else if (ws == 0 &&
                         !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
                    continue;                // loop on failed CAS
            }
            if (h == head)                   // loop if head changed
                break;
        }
    }
设置队列头,并检查后继节点是否是SHARED状态在等待
如果,是SHARED则向后传播
如果不是,设置waitStatus状态为PROPAGATE或者propagate > 0
propagate:从tryacquired返回的值
 private void setHeadAndPropagate(Node node, int propagate) {
        Node h = head; // Record old head for check below
        setHead(node);
        尝试唤醒队列中的下一个节点:
       		传播由调用者指示,
        	或者被先前的操作记录
        	(注意:这会使用waitStatus的签名,因为PROPAGATE 可以转换成SIGNAL)
        	并且
        	下一个节点以共享模式等待,
			或者我们不知道,因为它看起来是空的
		但是只要有多个竞争 acquires/releases(大多数需要尽快唤醒的情况下)
		这两种检查的保守性可能会导致不必要的唤醒,
        /*
         * Try to signal next queued node if:
         *   Propagation was indicated by caller,
         *     or was recorded (as h.waitStatus either before
         *     or after setHead) by a previous operation
         *     (note: this uses sign-check of waitStatus because
         *      PROPAGATE status may transition to SIGNAL.)
         * and
         *   The next node is waiting in shared mode,
         *     or we don't know, because it appears null
         *
         * The conservatism in both of these checks may cause
         * unnecessary wake-ups, but only when there are multiple
         * racing acquires/releases, so most need signals now or soon
         * anyway.
         */
        if (propagate > 0 || h == null || h.waitStatus < 0 ||
            (h = head) == null || h.waitStatus < 0) {
            Node s = node.next;
            if (s == null || s.isShared())
                doReleaseShared();
        }
    }

各种版本的acquire

取消正在进行的获取尝试
private void cancelAcquire(Node node) {
		如果node不存在,那么直接return// Ignore if node doesn't exist
        if (node == null)
            return;
            
		将node所在的线程置为空。
        node.thread = null;
		跳过已经取消的前驱节点
        // Skip cancelled predecessors
        Node pred = node.prev;

		waitStatus的值为1时,这个node标记为cancel
        while (pred.waitStatus > 0)
        这里执行的操作就是链表的删除中间节点。
            node.prev = pred = pred.prev;

        // predNext is the apparent node to unsplice. CASes below will
        // fail if not, in which case, we lost race vs another cancel
        // or signal, so no further action is necessary.
        pred节点的next需要重新定位。
        Node predNext = pred.next;

        // Can use unconditional write instead of CAS here.
        // After this atomic step, other Nodes can skip past us.
        // Before, we are free of interference from other threads.
        将当前节点重新将状态定义为CANELLLED
        node.waitStatus = Node.CANCELLED;
        
		如果这个当前需要取消尝试获取的节点是尾节点,就需要直接remove当前节点。
        // If we are the tail, remove ourselves.
        if (node == tail && compareAndSetTail(node, pred)) {
        |pred|---->|node|,如果pred的next和null相同则执行CAS操作。
            compareAndSetNext(pred, predNext, null);
        } else {
        如果当前节点的后继节点需要信号,尝试pred的next节点获得信号。否走唤醒将会传递 。
            // If successor needs signal, try to set pred's next-link
            // so it will get one. Otherwise wake it up to propagate.
            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
        }
    }
检查和更新未能获取的节点的状态
如果线程应该阻塞,返回true。
在所有的acquire循环中,这是最主要的信号控制。
需要 pred == node.prev
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
        int ws = pred.waitStatus;
        if (ws == Node.SIGNAL)
            /*
             * This node has already set status asking a release
             * to signal it, so it can safely park.
             */
            return true;
        if (ws > 0) {
            /*
             * Predecessor was cancelled. Skip over predecessors and
             * indicate retry.
             */
            do {
                node.prev = pred = pred.prev;
            } while (pred.waitStatus > 0);
            pred.next = node;
        } else {
            /*
             * waitStatus must be 0 or PROPAGATE.  Indicate that we
             * need a signal, but don't park yet.  Caller will need to
             * retry to make sure it cannot acquire before parking.
             */
            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
        }
        return false;
    }
方便方法中断当前线程
static void selfInterrupt() {
        Thread.currentThread().interrupt();
    }
方便方法去park并且检查当前线程是否被中断
如果是中断的,返回true
private final boolean parkAndCheckInterrupt() {
        LockSupport.park(this);
        return Thread.interrupted();
    }
exclusive && uninterrupted(在队列中的线程)
使用条件等待方法以及获取。
如果在等待时中断,返回truefinal 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);
        }
    }
exclusive && interrupted
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);
        }
    }
exclusive && timed
如果获取到了,返回trueprivate 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);
        }
    }
shared && uninterruptible
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);
        }
    }
shared && interruptible
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);
        }
    }
shared && timed
 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);
        }
    }

主要的外部使用方法

尝试在独占模式下获取(acquire)
此方法应该查询对象的状态是否允许以独占模式获取它,如果允许,则获取它。
protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }
尝试设置状态以反映排他模式下的释放。
 protected boolean tryRelease(int arg) {
        throw new UnsupportedOperationException();
    }

return:
在失败时为负值; 
零,如果采集在共享模式成功,但没有后续共享模式获取能成功;
如果共享模式下的获取成功,后续的共享模式获取也可能成功,则该值为正值,
在这种情况下,后续的等待线程必须检查可用性。
(对三个不同的返回值的支持使得这个方法可以在只在特定情况下进行获取的上下文中使用)
当成功时,这个对象已经被获取。
protected int tryAcquireShared(int arg) {
        throw new UnsupportedOperationException();
    }
    
protected boolean tryReleaseShared(int arg) {
        throw new UnsupportedOperationException();
    }
返回值是true,则说明当前线程的同步是独占模式。
protected boolean isHeldExclusively() {
        throw new UnsupportedOperationException();
    }
获取处于独占模式并且忽略中断。通过调用至少一次tryAcquire来实现,成功后返回。
否则,线程会排队,可能会反复的阻塞和解除阻塞,调用tryAcquire直到成功。
这个方法可以用来实现方法Lock.lock。
public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }
获取处于独占模式,中断时终止。
首先判断是否被中断,如果已经被中断,那么抛出中断异常。
如果没有被中断,那么再判断是否已经获取到了(是否tryAcquire成功)
如果没有获取到,那么执行doAcquireInterruptibly方法尝试可中断的获取。
如果获取到了,那么跟直接return。
可以用来实现Lock.lockInterruptibly.

public final void acquireInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        if (!tryAcquire( arg))
            doAcquireInterruptibly(arg);
    }
尝试以排他模式获取,如果被中断将中止,如果给定的时间超时失败。
首先检查中断状态,然后至少调用一次 tryAcquire,成功后返回。
否则,线程排队,可能反复的阻塞和解除阻塞,调用 tryAcquire,直到成功,或者线程被中断或超时结束。
这个方法可以用来实现方法 Lock.tryLock(long, TimeUnit)}return true: 获取成功。
return false: 超时。
public final boolean tryAcquireNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        return tryAcquire(arg) ||
            doAcquireNanos(arg, nanosTimeout);
    }
以独占模式释放。如果tryRelease返回true,通过解除一个或多个线程的阻塞来实现。
这个方法可以用来实现方法Lock.unlock。
首先判断是否释放(release)成功:
如果是,那么再判断等待对列的头结点是否为空 && 头结点的状态值不为0(节点不处于初始化状态)。
说明本身就有一个线程对应的节点在等待对列中等待,这时执行unparkSuccessor
public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }
在共享模式下acquire,忽略中断。
首先至少调用一次 tryAcquireShared,成功返回。
否则线程将会进入等待对列,调用tryAcquireShared直到成功,并且可能重复blocking and unblocking。
tryAcquireShared(arg) < 0 表示tryAcquireShared失败
 public final void acquireShared(int arg) {
        if (tryAcquireShared(arg) < 0)
            doAcquireShared(arg);
    }
在共享模式中获取,如果中断将中止。
首先检查中断状态,然后至少调用一次tryacquiremred,成功后返回。
否则,线程被排队,可能反复blocking 和 unblocking,调用 tryacquiremred,直到成功或线程被中断。
首先判断线程是否被中断,如果被中断,则抛出中断异常。
如果么有被中断,再判断tryAcquireShared是否成功,
如果没成功tryAcquireShared(arg) < 0 那么执行doAcquireSharedInterruptibly(arg);
如果成功,直接返回。
 public final void acquireSharedInterruptibly(int arg)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        if (tryAcquireShared(arg) < 0)
            doAcquireSharedInterruptibly(arg);
    }

多出一个超时判断,
returntrue:
如果在共享模式下可以获取成功tryAcquireShared(arg) >= 0 
 或者没有获取成功,但是doAcquireSharedNanos(arg, nanosTimeout)没有超时;
 falsetryAcquireShared(arg) < 0 没有获取成功 && 超时了。
public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        return tryAcquireShared(arg) >= 0 ||
            doAcquireSharedNanos(arg, nanosTimeout);
    }
共享模式下release。
如果tryReleaseShared返回true,则通过解除阻塞一个或多个线程来实现。
public final boolean releaseShared(int arg) {
        if (tryReleaseShared(arg)) {
            doReleaseShared();
            return true;
        }
        return false;
    }

队列检验方法

查询是否有线程等待获取。
注意,由于中断和超时导致的取消可能随时发生,返回true不能保证任何其他线程将acquire。
 public final boolean hasQueuedThreads() {
        return head != tail;
    }
查询是否有线程争用此同步器;这也就是说是否曾经有一个acquire方法被阻塞。
如果有,就说明曾经发生有对该同步器的争夺,返回true;
反之,返回falsepublic final boolean hasContended() {
        return head != null;
    }
返回队列中的第一个节点(最长等待),如果为空,说明此时队列中没有节点。
通常来说,这个方法在有限时间内返回,
但是如果有别的线程正在修改队列,那么可能迭代自旋,争夺权限。
 public final Thread getFirstQueuedThread() {
        // handle only fast path, else relay
        return (head == tail) ? null : fullGetFirstQueuedThread();
    }
getFirstQueuedThread的一个补救版本(fastpath 失败时);
private Thread fullGetFirstQueuedThread() {
通常第一个节点必然是head.next。
尝试获取线程域,并且却白读取到的数据一致:
如果线程域空出或者s.prev不在指向头结点,那么其他线程并发执行setHead(在读操作的间隙)。
在使用遍历之前,我们尝试setHead操作两次。
h:头结点;
s:头结点.next;
判别条件
如果:头结点h不为空 && h.next不为空 && s.prev是头结点 && s节点此时代表一个线程
(h = head) != null && (s = h.next) != null 
&& s.prev == head && (st = s.thread) != null)
或者:
和上半部一样的判断再执行一次。
        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;
头节点的下一个节点可能还没有被设置完成,或者在setHead后没有被设置。
所以必须检查尾节点实际上是否是第一个节点。
如果不是,我们继续从尾部节点开始反向遍历直到终止。
     
        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;
    }
如果给定线程在当前队列中,则返回true。
此方法将遍历队列以确定给定线程的存在。
 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;
    }
如果第一个排队的线程以排他模式等待,返回true。
如果这个方法返回true,并且当前线程正在以共享模式尝试获取,那么就可以确定当前线程不是第一个排队的线程。
在ReentrantReadWriteLock中用作启发式。
final boolean apparentlyFirstQueuedIsExclusive() {
        Node h, s;
        return (h = head) != null &&
            (s = h.next)  != null &&
            !s.isShared()         &&
            s.thread != null;
    }
查询是否有线程等待获取的时间大于当前线程。
此方法调用等价于(可能比等价方法更高效):
getFirstQueuedThread() != Thread.currentThread() && hasQueuedThreads()

注意,由于中断和超时导致的取消可能随时发生, true返回不能保证其他线程将在当前线程之前获得。
同样,由于队列为空,在此方法返回false后,其他线程也可能在排队竞赛中获胜。

此方法被设计为由一个公平的同步器使用,以避免冲突。
这种同步器的tryAcquire方法应该返回 false,如果该方法返回true(除非是可重入获取),
那么它的 tryacquiresred方法应该返回一个负值。

如果当前线程之前有一个排队的线程,则为true;
如果当前线程位于队列的头部或队列为空,则为falsepublic final boolean hasQueuedPredecessors() {
 这个正确性依赖于:头结点在尾结点之前初始化;
 				如果当前线程是第一个入队的,那么头结点的下一个节点必须是精确的。
      tail以相反的初始化顺序读取字段。
        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());
    }

仪器工具和监视方法

返回 等待require方法的线程的数量的估计值。
这个数量是估计值,是因为线程数量是会一直处在一个动态变化的状态。
这个方法用来监视系统状态,不作为同步控制。
 public final int getQueueLength() {
        int n = 0;
        for (Node p = tail; p != null; p = p.prev) {
            if (p.thread != null)
                ++n;
        }
        return n;
    }
返回一个集合——等待require方法的线程的集合。
由于确切的线程在我们构造这一集合时可能动态的在变化,所以这个结果只能是最优估计。
集合中的元素排序不分先后。
这种方法旨在促进子类的构建,从而提供更广泛的监控工具。
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;
    }
返回一个集合——等待require方法的线程(独占式)的集合
 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;
    }
返回一个集合——等待require方法的线程(共享式)的集合
 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]";
    }

支持Condition的内部方法

返回true:如果节点(总是最初放置在条件队列中的节点)在同步队列中等待二次acquire
 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;
        节点node.prev可以确保非空,但是不会马上出现在队列上,这是因为CAS放置节点的操作可能失败。
        所以我们必须从尾部开始遍历,确保CAS操作成功。
        在对这个方法的调用中,它总是在尾部附近,除非CAS失败(这是不可能的),否则它就会在那里,
        所以我们几乎不怎么遍历。
        return findNodeFromTail(node);
    }
如果从尾部遍历同步队列,发现节点node存在,则返回true。
只有isOnSyncQueue(Node 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;
    }
如果有必要,在取消等待后,将节点转移到同步队列。
如果线程在被signal之前就取消了,那么返回truefinal boolean transferAfterCancelledWait(Node node) {
        if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
            enq(node);
            return true;
        }
        如果signal失败,直到signal成功,我们才可以进行下一步。
        在未完成节点转移的操作中做取消操作是非常罕见和短暂的,所以只要自旋一会就好。
        while (!isOnSyncQueue(node))
            Thread.yield();
        return false;
    }
用当前的state值执行release操作,并且返回已经保存的状态。
取消节点,并在失败时抛出异常。
return:上一次的状态。
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;
        }
    }

Condition的仪表工具

查询给定的条件对象ConditionObject是否使用此同步器作为其锁。

 public final boolean owns(ConditionObject condition) {
        return condition.isOwnedBy(this);
    }
查询是否有线程在等待与此同步器关联的Condition。
注意,因为超时和中断可能在任何时候发生,true返回不能保证将来的signal方法将唤醒任何线程。
这种方法主要用于监视系统状态。
 public final boolean hasWaiters(ConditionObject condition) {
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.hasWaiters();
    }

返回线程数量的估计值,这些线程等待在与此同步器相关的Condition上。
注意,因为超时和中断可能随时发生,所以估计值仅作为等待者实际数量的上限。
这种方法是为监控系统状态而设计的,不是为同步控制而设计的。
public final int getWaitQueueLength(ConditionObject condition) {
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.getWaitQueueLength();
    }
返回一个包含了等待在同步器相关的Condition上的线程的集合。
注意,因为超时和中断可能随时发生,所以估计值仅是最好的估计值。
返回的集合没有特定的顺序。
 public final Collection<Thread> getWaitingThreads(ConditionObject condition) {
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.getWaitingThreads();
    }

ConditionObject内部类

public class ConditionObject implements Condition, java.io.Serializable {
        private static final long serialVersionUID = 1173984872572414699L;
        条件队列的第一个节点
        private transient Node firstWaiter;
        条件队列的最后一个节点
        private transient Node lastWaiter;

        创建一个新的ConditionObject实例
        public ConditionObject() { }  

内部方法

 // Internal methods
		在等待队列中添加一个新的节点。
		return : 新的等待节点。
      
        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;
        }
		移除并且转移node直到遇到一个状态不是cancel的节点或者遇到空。
		由信号拆分出来,去支持编译器去内联没有等待节点的情况。
       参数:first 条件队列的第一个节点
        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);
        }
        
		从条件队列中取消已经处在cancel状态节点的链接。
		仅在持有锁时调用。
		当取消在条件等待期间发生时,以及当看到lastWaiter被取消时插入一个新服务员时,调用这个函数。
		在没有信号的情况下,需要使用这种方法来避免垃圾堆积。
		因此,即使它可能需要一个完整的遍历,它也只有在没有信号的同时出现超时或取消时才发挥作用。
		它会遍历所有节点,而不是在某个特定目标上停止,以断开所有指向垃圾节点的指针的链接,
		而不需要在取消风暴期间进行多次重新遍历。
      
        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);
        }
	实现不可中断条件等待。
	1.保存由getState方法返回的锁状态
	2.利用保存好的state执行release方法,作为判断依据,如果失败,抛出异常。
	3.保持阻塞状态直到被signal
	4.通过执行以state为依据的acquire方法,二次获取。
       
        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();
        }
		对于可中断的等待,如果在阻塞条件下被中断,我们需要跟踪:
		如果在阻塞条件下中断,抛出异常InterruptedException;
		如果在阻塞条件下等待二次require,再次获取当前线程。

        退出等待时重新中断。
        private static final int REINTERRUPT =  1;
       退出等待时抛出异常。
        private static final int THROW_IE    = -1;
		对中断的检查,在signal前被中断,则返回THROW_IE ;
		在signal后被中断,返回REINTERRUPT;
		如果没有中断,返回0private int checkInterruptWhileWaiting(Node node) {
            return Thread.interrupted() ?
                (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
                0;
        }
		抛出InterruptedException异常,重新中断当前线程;
		或什么都不做。
		由参数判断。
      
        private void reportInterruptAfterWait(int interruptMode)
            throws InterruptedException {
            if (interruptMode == THROW_IE)
                throw new InterruptedException();
            else if (interruptMode == REINTERRUPT)
                selfInterrupt();
        }
		实现可中断条件等待:
		1.如果当前线程已经中断,抛出InterruptedException异常;
		2.保存由getState方法返回的state值;
		3.以获得的state值为依据执行release方法,如果失败抛出IllegalMonitorStateException;
		4.阻塞,直到被signal或者被中断;
		5.依据获得的state值调用特殊的require版本实现再次获取;
		6.如果在步骤4被中断,抛出InterruptedException
        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);
        }
		实现限时条件等待
		1.如果当前线程被中断,抛出InterruptedException;
		2.保存由getState方法返回的state值;
		3.以获得的state值为依据执行release方法,如果失败抛出IllegalMonitorStateException;
		4.阻塞,直到被signal或者被中断或者超时;
		5.依据获得的state值调用特殊的require版本实现再次获取;
		6.如果在步骤4中因为阻塞而中断,抛出InterruptedException。
      
        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();
        }
		实现了绝对定时条件等待。
		1.如果当前线程被中断,抛出InterruptedException;
		2.保存由getState方法返回的state值;
		3.以获得的state值为依据执行release方法,如果失败抛出IllegalMonitorStateException;
		4.阻塞,直到被 signal或者 被中断或者 超时;
		5.依据获得的state值调用特殊的require版本实现再次获取;
		6.如果在步骤4中因为阻塞而中断,抛出InterruptedException;
		7.如果在步骤4中阻塞时超时,则返回false,否则返回truepublic 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;
        }
		实现定时条件等待
		
        /**
         * Implements timed condition wait.
         * <ol>
         * <li> If current thread is interrupted, throw InterruptedException.
         * <li> Save lock state returned by {@link #getState}.
         * <li> Invoke {@link #release} with saved state as argument,
         *      throwing IllegalMonitorStateException if it fails.
         * <li> Block until signalled, interrupted, or timed out.
         * <li> Reacquire by invoking specialized version of
         *      {@link #acquire} with saved state as argument.
         * <li> If interrupted while blocked in step 4, throw InterruptedException.
         * <li> If timed out while blocked in step 4, return false, else true.
         * </ol>
         */
        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;
        }

支持工具

如果这个condition是由给定的同步对象创建的,则返回true/**
         * @return {@code true} if owned
         */
        final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
            return sync == AbstractQueuedSynchronizer.this;
        }

查询是否有线程等待此条件。
实现: public final boolean hasWaiters(ConditionObject condition) 方法
       
        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;
        }
	返回等待此条件的线程数的估计数。
	实现:public final int getWaitQueueLength(ConditionObject condition)方法
      
        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;
        }
返回一个集合,其中包含可能正在等待此条件的线程。
实现:public final Collection<Thread> getWaitingThreads(ConditionObject condition)方法
       
        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;
        }
    }

CAS

 /**
     * Setup to support compareAndSet. We need to natively implement
     * this here: For the sake of permitting future enhancements, we
     * cannot explicitly subclass AtomicInteger, which would be
     * efficient and useful otherwise. So, as the lesser of evils, we
     * natively implement using hotspot intrinsics API. And while we
     * are at it, we do the same for other CASable fields (which could
     * otherwise be done with atomic field updaters).
     */
    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); }
    }

    /**
     * CAS head field. Used only by enq.
     */
    private final boolean compareAndSetHead(Node update) {
        return unsafe.compareAndSwapObject(this, headOffset, null, update);
    }

    /**
     * CAS tail field. Used only by enq.
     */
    private final boolean compareAndSetTail(Node expect, Node update) {
        return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
    }

    /**
     * CAS waitStatus field of a node.
     */
    private static final boolean compareAndSetWaitStatus(Node node,
                                                         int expect,
                                                         int update) {
        return unsafe.compareAndSwapInt(node, waitStatusOffset,
                                        expect, update);
    }

    /**
     * CAS next field of a node.
     */
    private static final boolean compareAndSetNext(Node node,
                                                   Node expect,
                                                   Node update) {
        return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值