Condition

一、概述

 Condition就是维护一个条件队列,当AQS的线程在lock()内Condition.await()后,该线程会释放锁,然后进入Condition的条件队列,当别的线程Condition.signal()唤醒他后,他会进入AQS的同步队列等待获得锁

核心方法:await()、signal()、signalAll()

 

二、源码

1、接口

public interface Condition {
    //当前线程在接到信号或中断之前一直处于等待状态
    void await() throws InterruptedException;
    //当前线程在接到信号或中断之前一直处于等待状态,如果超时则返回false
    boolean await(long time, TimeUnit unit) throws InterruptedException;
    //当前线程在接到信号或中断之前一直处于等待状态,如果超时则返回-1,没超时就返回剩余的等待时间
    long awaitNanos(long nanosTimeout) throws InterruptedException;
    //当前线程在接到信号或中断之前一直处于等待状态,如果超过最后期限则返回false
    boolean awaitUntil(Date deadline) throws InterruptedException;
    //无法中断的等待
    void awaitUninterruptibly();
    //唤醒一个等待线程,线程必须先获得锁
    void signal();
    //唤醒所有等待线程,能返回的线程必须获取相关的锁
    void signalAll();
}

 

2、属性

//队列的首节点
private transient Node firstWaiter;
//队列的尾节点
private transient Node lastWaiter;

//代表线程是在 signal 后被中断的
private static final int REINTERRUPT =  1;
//代表线程是在 signal 前被中断的
private static final int THROW_IE    = -1;

 

3、私有方法

//添加lastWaiter
private Node addConditionWaiter() {
    Node t = lastWaiter;
    //如果lastWaiter是取消状态
    if (t != null && t.waitStatus != Node.CONDITION) {
        //向前清理取消状态的waiter
        unlinkCancelledWaiters();
        t = lastWaiter;
    }
    //创建新节点,作为lastWaiter
    Node node = new Node(Thread.currentThread(), Node.CONDITION);
    if (t == null)
        firstWaiter = node;
    else
        t.nextWaiter = node;
    lastWaiter = node;
    return node;
}

//向前清理取消状态的waiter
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;
    }
}

//删除或者转移节点到同步队列中,直到获取的节点是不可取消节点,或者null
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 int checkInterruptWhileWaiting(Node node) {
    return Thread.interrupted() ? (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) : 0;
}

//根据interruptMode来确定是应该抛出InterruptedException还是继续中断
private void reportInterruptAfterWait(int interruptMode)
    throws InterruptedException {
    if (interruptMode == THROW_IE)
        throw new InterruptedException();
    else if (interruptMode == REINTERRUPT)
        selfInterrupt();
}

  

4、公共方法

public ConditionObject() { }

public final void signal() {
    //只有用到condition才需要实现,判断当前线程是否获得独占锁
    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();
}

public final void await() throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    Node node = addConditionWaiter();
    //放弃所有持有的锁
    int savedState = fullyRelease(node);
    int interruptMode = 0;
    //阻塞判断,当前node是不是在同步队列时,不在同步队列那么就park当前线程
    while (!isOnSyncQueue(node)) {
        LockSupport.park(this);
        //如果被中断了,则检测中断
        if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
            break;
    }
    //这是此节点已经在同步队列中了
    //在队列中获取锁,并判断当前的interruptMode不为-1,即不是抛出异常
    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;
}

  

5、辅助方法

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

  

posted @ 2020-03-09 01:29  syxsdhy  阅读(533)  评论(0编辑  收藏  举报