juc1-locks-AbstractQueuedSynchronizer

一 类结构

类结构.png
  • AbstractQueuedLongSynchronizer与AbstractQueuedSynchronizer类结构和功能相同,唯一的区别是表示锁状态的state一个是long类型,一个是int类型。后面仅说明AbstractQueuedSynchronizer的实现。
 /**
     * The synchronization state.
     */
    private volatile long state;//AbstractQueuedLongSynchronizer

    private volatile int state;//AbstractQueuedSynchronizer
  • volatile介绍
    *并发包中的XXXLock锁类基于AbstractQueuedSynchronizer实现锁的控制

二 AbstractOwnableSynchronizer

  • Thread exclusiveOwnerThread;表示当前获取到锁的线程。
public abstract class AbstractOwnableSynchronizer
    implements java.io.Serializable {

    /** Use serial ID even though all fields transient. */
    private static final long serialVersionUID = 3737899427754241961L;

    /**
     * Empty constructor for use by subclasses.
     */
    protected AbstractOwnableSynchronizer() { }

    /**
     * The current owner of exclusive mode synchronization.
     */
    private transient Thread exclusiveOwnerThread;

    /**
     * Sets the thread that currently owns exclusive access.
     * A {@code null} argument indicates that no thread owns access.
     * This method does not otherwise impose any synchronization or
     * {@code volatile} field accesses.
     * @param thread the owner thread
     */
    protected final void setExclusiveOwnerThread(Thread thread) {
        exclusiveOwnerThread = thread;
    }

    /**
     * Returns the thread last set by {@code setExclusiveOwnerThread},
     * or {@code null} if never set.  This method does not otherwise
     * impose any synchronization or {@code volatile} field accesses.
     * @return the owner thread
     */
    protected final Thread getExclusiveOwnerThread() {
        return exclusiveOwnerThread;
    }
}

三 AbstractQueuedSynchronizer

  • static final long spinForTimeoutThreshold = 1000L; 短暂自旋时间1ms
  • 计算属性偏移值,Unsafe的cas函数原子更改属性值使用
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); }
}

3.1 锁

3.1.1 锁状态

/**
     * The synchronization state.
     */
    private volatile int state;

3.1.2 锁状态查询函数

 /**
     * Returns the current value of synchronization state.
     * This operation has memory semantics of a {@code volatile} read.
     * @return current state value
     */
    protected final int getState() {
        return state;
    }

3.1.3 锁状态修改函数

/**
     * Sets the value of synchronization state.
     * This operation has memory semantics of a {@code volatile} write.
     * @param newState the new state value
     */
    protected final void setState(int newState) {
        state = newState;
    }

    /**
     * Atomically sets synchronization state to the given updated
     * value if the current state value equals the expected value.
     * This operation has memory semantics of a {@code volatile} read
     * and write.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful. False return indicates that the actual
     *         value was not equal to the expected value.
     */
    protected final boolean compareAndSetState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }

3.2 等待锁

  • 尝试获取锁失败的线程,构建等待锁节点,放入等待锁队列中
  • 节点队列头尾节点
    /**
     * Head of the wait queue, lazily initialized.  Except for
     * initialization, it is modified only via method setHead.  Note:
     * If head exists, its waitStatus is guaranteed not to be
     * CANCELLED.
     */
    private transient volatile Node head;

    /**
     * Tail of the wait queue, lazily initialized.  Modified only via
     * method enq to add new wait node.
     */
    private transient volatile Node tail;

3.2.1 等待节点

  • 节点结构
static final class Node {
    /** Marker to indicate a node is waiting in shared mode */
    static final AbstractQueuedSynchronizer.Node SHARED = new AbstractQueuedSynchronizer.Node();
    /** Marker to indicate a node is waiting in exclusive mode */
    static final AbstractQueuedSynchronizer.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;
    //节点状态
    volatile int waitStatus;

    //前后节点引用
    volatile AbstractQueuedSynchronizer.Node prev;
    volatile AbstractQueuedSynchronizer.Node next;
    //等待锁的线程
    volatile Thread thread;

    //1 作为条件对象的等待节点链表,
    //2 作为等待锁节点,表示是否为共享模式,是则为SHARED对象,不是则为null
    AbstractQueuedSynchronizer.Node nextWaiter;

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

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

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

    Node(Thread thread, AbstractQueuedSynchronizer.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;
    }
}
  • 节点状态流转


    节点状态.png

3.2.2 入队

3.2.2.1 enq

  • 添加到等待锁节点队列中
  • addWaiter()添加共享模式或独占模式的等待锁节点
  • transferAfterCancelledWait()或transferForSignal()从条件对象等待队列中迁移到等待锁队列中
private Node enq(final Node node) {
    for (;;) {//不断循环直到入队成功
        Node t = tail;
        if (t == null) { // 首次初始化
            //先设置head,后更新tail。
            if (compareAndSetHead(new Node()))
                tail = head;
        } else {
            node.prev = t;
            //cas更新尾节点tail,更新成功则修改next属性,否则重现更新
            if (compareAndSetTail(t, node)) {
                t.next = node;
                return t;
            }
        }
    }
}

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

3.2.2.2 addWaiter

  • 实现如下
private Node addWaiter(Node mode) {
    Node node = new Node(Thread.currentThread(), mode);
    // Try the fast path of enq; backup to full enq on failure
    Node pred = tail;
    if (pred != null) {//先尝试添加一次,添加失败则进入enq()
        node.prev = pred;
        if (compareAndSetTail(pred, node)) {
            pred.next = node;
            return node;
        }
    }
    enq(node);
    return node;
}
  • 在获取锁接口调用时,先按独占模式或共享模式节点插入队列。然后再尝试获取锁。
    acquire()获取独占锁,acquireShared()获取共享锁。

3.2.2.3 transferAfterCancelledWait

  • 超时或收到signal通知两种情况会迁移节点到等待锁队列中。
  • 从条件对象等待队列的Node.CONDITION类型节点,更改状态为0,插入等待锁队列
final boolean transferAfterCancelledWait(Node node) {
    if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
        enq(node);
        return true;
    }
   //迁移失败,则有signal通知迁移,自旋等待迁移完成
    while (!isOnSyncQueue(node))//等待signal迁移到等待锁队列中。
        Thread.yield();
    return false;
}
  • 判断是否节点在等待锁队列中
final boolean isOnSyncQueue(Node node) {
//Node.CONDITION为条件对象队列节点状态
//等待锁队列是双链表,条件对对象队列是单链表
    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;
    }
}

3.2.2.4 transferForSignal

final boolean transferForSignal(Node node) {
    //修改状态失败,表示已经超时完成迁移节点了
    if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
        return false;

   //入队后,若节点状态为cancel=1,或状态无法更改为signal,则唤醒线程继续处理
    Node p = enq(node);
    int ws = p.waitStatus;
    if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
        LockSupport.unpark(node.thread);
    return true;
}

3.2.3 出队

3.2.3.1 setHead

  • 获取锁成功后,设置线程节点为头节点。
  • 释放原头节点
private void setHead(Node node) {
    head = node;
    node.thread = null;
    node.prev = null;
}

3.2.3.2 setHeadAndPropagate

  • 获取共享锁成功,修改线程节点为头节点。还有可共享锁资源,则通知等待共享锁的节点获取锁。
  • 释放原头节点
private void setHeadAndPropagate(Node node, int propagate) {
    Node h = head; // Record old head for check below
    setHead(node);
    // propagate可共享锁数量,
    if (propagate > 0 || h == null || h.waitStatus < 0 ||
            (h = head) == null || h.waitStatus < 0) {
        Node s = node.next;
        if (s == null || s.isShared())
           //有多余锁资源,唤醒等待共享锁的节点,再次尝试获取锁
            doReleaseShared();
    }
}

3.3 获取锁

3.3.1 获取独占锁

  • 锁类内部继承子类实现tryAcquire(),尝试获取锁
  • 尝试获取锁失败后,addWaiter(Node.EXCLUSIVE)插入独占类型等待锁节点
  • 调用acquireQueued()获取锁
public final void acquire(int arg) {
    if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
        selfInterrupt();
}
  • acquireQueued
final boolean acquireQueued(final Node node, int arg) {
    boolean failed = true;
    try {
        boolean interrupted = false;
        for (;;) {
            final Node p = node.predecessor();
            //head节点为占用锁的节点,若前节点为head,则尝试获取锁一次
            if (p == head && tryAcquire(arg)) {
                //获取锁成功,更新head节点,释放原head节点
                setHead(node);
                p.next = null; // help GC
                failed = false;
                return interrupted;
            }
           //更改当前节点为等待锁状态,休眠等待唤醒
            if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
//被中断后仅纪录一下状态,不可被中断
                interrupted = true;
        }
    } finally {
        if (failed)//获取失败,则取消等待锁。
            cancelAcquire(node);
    }
}
  • shouldParkAfterFailedAcquire()
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
    int ws = pred.waitStatus;
    if (ws == Node.SIGNAL)
        return true;
    if (ws > 0) {//节点状态为cancel
        do {//循环遍历删除cancel状态节点
            node.prev = pred = pred.prev;
        } while (pred.waitStatus > 0);
        pred.next = node;
    } else {
       //修改节点状态为SIGNAL
        compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
    }
    return false;
}
  • parkAndCheckInterrupt(),休眠等待唤醒
private final boolean parkAndCheckInterrupt() {
    LockSupport.park(this);
    return Thread.interrupted();
}

3.3.1.1 可中断获取独占锁

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

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())
//被中断后跑出InterruptedException
                throw new InterruptedException();
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}

3.3.1.2 限时尝试获取锁

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

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)//超时返回false
                return false;
          //spinForTimeoutThreshold=1ms,小于1ms则不休眠直接退出
            if (shouldParkAfterFailedAcquire(p, node) &&
                    nanosTimeout > spinForTimeoutThreshold)
                //指定休眠时间,超时则获取锁失败,
                LockSupport.parkNanos(this, nanosTimeout);
            if (Thread.interrupted())//可中断
                throw new InterruptedException();
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}

3.3.2 共享锁

  • 包含不可中断获取锁,可中断获取锁,限时可中断获取锁三种类型。实现区别和独占锁的三种获取方式实现区别相同
  • 不可中断获取锁
public final void acquireShared(int arg) {
    if (tryAcquireShared(arg) < 0)//子类实现尝试获取锁接口
        doAcquireShared(arg);
}
  • doAcquireShared
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) {//前节点为head,head为占有锁的节点,则当前节点尝试获取锁
                int r = tryAcquireShared(arg);
                if (r >= 0) {//有多余的共享锁资源,则唤醒后续等待锁节点获取共享锁
                    setHeadAndPropagate(node, r);
                    p.next = null; // help GC
                    if (interrupted)
                        selfInterrupt();
                    failed = false;
                    return;
                }
            }
//修改节点状态为signal,休眠等待唤醒
            if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                interrupted = true;
        }
    } finally {
        if (failed)//异常则取消获取锁
            cancelAcquire(node);
    }
}

3.4 释放锁

3.4.1 释放独占锁

public final boolean release(int arg) {
    if (tryRelease(arg)) {//子类实现释放锁接口
        Node h = head;
        if (h != null && h.waitStatus != 0)
//唤醒后续节点尝试获取锁,后续节点获取到锁后会释放当前占有锁的头节点
            unparkSuccessor(h);
        return true;
    }
    return false;
}

3.4.2 释放共享锁

  • 通知可获取共享锁的节点
public final boolean releaseShared(int arg) {
    if (tryReleaseShared(arg)) {
        doReleaseShared();
        return true;
    }
    return false;
}

private void doReleaseShared() {
    for (;;) {
        Node h = head;
        if (h != null && h != tail) {//从头节点卡诗遍历
            int ws = h.waitStatus;
            if (ws == Node.SIGNAL) {
               //signal状态的节点,则更改状态为0并唤醒线程尝试获取锁。
               //获取锁失败的节点会设置节点状态为SIGNAL或条件对象通知迁移到等待锁队列的节点状态为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;
    }
}

3.4.3 unparkSuccessor

private void unparkSuccessor(Node node) {
    // 状态为负数,更改为0,尝试获取锁
    int ws = node.waitStatus;
    if (ws < 0)
        compareAndSetWaitStatus(node, ws, 0);

    Node s = node.next;
    if (s == null || s.waitStatus > 0) {
        s = null;//下一节点为null或被cancel。则从尾节点向前查询直到头节点,查找状态为负数的节点。即等待锁的节点。
        for (Node t = tail; t != null && t != node; t = t.prev)
            if (t.waitStatus <= 0)
                s = t;
    }
    if (s != null)//有等待锁的节点,则唤醒线程尝试获取锁
        LockSupport.unpark(s.thread);
}

3.5 cancel节点

  • 尝试获取锁时有异常,或被中断,则修改节点为CANCELLED状态,不再尝试获取锁
private void cancelAcquire(Node node) {
    // Ignore if node doesn't exist
    if (node == null)
        return;
    node.thread = null;
    Node pred = node.prev;
   //跳过已cancel的前节点,即释放cancel节点
    while (pred.waitStatus > 0)
        node.prev = pred = pred.prev;

    Node predNext = pred.next;
    node.waitStatus = Node.CANCELLED;
    // 当前节点为尾节点,则修改尾节点为前节点,更改前节点next为null
    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
    }
}

四 条件对象ConditionObject

  • 条件对象等待队列首尾节点
/** First node of condition queue. */
private transient Node firstWaiter;
/** Last node of condition queue. */
private transient Node lastWaiter;

4.1 休眠等待通知

4.1.1 不可中断等待

  • 加锁后调用,所以无需考虑并发问题
  • awaitUninterruptibly()
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();//被中断,则抛中断
}

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

static void selfInterrupt() {
    Thread.currentThread().interrupt();
}
  • addConditionWaiter()
private Node addConditionWaiter() {
    Node t = lastWaiter;
    // If lastWaiter is cancelled, clean out.
    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;
}
  • unlinkCancelledWaiters() 删除等待条件对象链表中国年非CONDITION状态节点
private void unlinkCancelledWaiters() {
    Node t = firstWaiter;
    Node trail = null;
    while (t != null) {//遍历链表
        Node next = t.nextWaiter;
        if (t.waitStatus != Node.CONDITION) {//删除非CONDITION节点
            t.nextWaiter = null;
            if (trail == null)
                firstWaiter = next;
            else
                trail.nextWaiter = next;
            if (next == null)
                lastWaiter = trail;
        }
        else
            trail = t;
        t = next;
    }
}

4.1.2 可中断等待

public final void await() throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    Node node = addConditionWaiter();//添加等待条件对象的condition状态节点
    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);
}

4.1.3 限时等待

  • awaitUntil(Date deadline),await(long time, TimeUnit unit),awaitNanos(long nanosTimeout)都是限时等待条件对象通知。实现差不多
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();
}

4.2 条件对象通知

4.2.1 signal()

public final void signal() {
    if (!isHeldExclusively())
        throw new IllegalMonitorStateException();
    Node first = firstWaiter;
    if (first != null)
        doSignal(first);
}
//单链表,先进先出通知第一个等待节点迁移到等待锁队列中
private void doSignal(Node first) {
    do {
        if ( (firstWaiter = first.nextWaiter) == null)
            lastWaiter = null;
        first.nextWaiter = null;
    } while (!transferForSignal(first) &&
            (first = firstWaiter) != null);
}

4.2.2 signalAll()

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

//通知所有等待条件对象节点迁移到等待锁队列中,尝试获取锁
private void doSignalAll(Node first) {
    lastWaiter = firstWaiter = null;
    do {
        Node next = first.nextWaiter;
        first.nextWaiter = null;
        transferForSignal(first);
        first = next;
    } while (first != null);
}

4.3 其他功能

  • 中断通知
private void reportInterruptAfterWait(int interruptMode)
        throws InterruptedException {
    if (interruptMode == THROW_IE)//抛中断异常
        throw new InterruptedException();
    else if (interruptMode == REINTERRUPT)
        selfInterrupt();//线程中断标记
}
  • 判断条件对象是否属于当前锁对象
final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
    return sync == AbstractQueuedSynchronizer.this;
}

五 总结

  • 提供一个支持同步锁的框架,双链表存储一个先进先出的等待锁队列。
  • 使用volatile变量表示锁状态
  • 子类通过getState()获取锁状态,setState(int newState)和compareAndSetState(int expect, int update)更新锁状态
  • 子类需要通过锁状态查询和更改接口实现如下接口尝试获取或释放锁。
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();
}
  • 独占锁类型下,支持conditionObject,即wait,singnal。内部存储一个等待条件对象通知的单链表
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • 商品社会是没有爱没有慈悲没有怜悯的生存竞技场,是野蛮血腥残忍交织刺激的斗兽场,这里只有胜利者失去理智以后疯狂...
    痖镛阅读 162评论 0 1
  • 需求 请实现一个函数,使其能将字符串转换成整数。 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非...
    惑也阅读 607评论 0 1