JDK8-AQS源码四之ConditionObject类

三月香巢已垒成,梁间燕子太无情!

前言

AQS的另外一个public的内部类ConditionObject,有木有觉得有点像谁呢,对的,它的粑粑就是前面介绍的Condition接口哦,他实现了 Condition和java.io.Serializable接口,ConditionObject内部维护了一个单向的链表,表示条件队列,它的节点状态只能为独占模式。

ps:条件队列和同步队列都是属于等待队列,以前老是将等待队列简单理解为条件队列了(Moves all threads from the wait queue for this condition to the wait queue for the owning lock.)。

构造函数

  //只有这一个无参构造函数
  public ConditionObject() { }

属性

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

    //退出等待时重新中断
    private static final int REINTERRUPT =  1;
    //退出等待是抛出InterruptedException
    private static final int THROW_IE    = -1;

方法

1.private方法

    //检查节点的中断状态, 在signalled之前被中断了返回THROW_IE ,
    //在signalled之后中断了,那么返回REINTERRUPT 
    //如果没有被中断,那么返回0.
    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();
    }

    //移除条件队列中被cancled的节点。调用这个方法,要求必须获取了锁。
    //当节点在等待条件时被取消,或者当插入一个新的节点的时候
    //最后一个节点已经被cancled了,那么将会调用这个方法。
    private void unlinkCancelledWaiters() {
        Node t = firstWaiter;
        Node trail = null;
        while (t != null) {
            Node next = t.nextWaiter;
            if (t.waitStatus != Node.CONDITION) {
                //断开与next的连接
                t.nextWaiter = null;
                if (trail == null)
                    firstWaiter = next;
                else
                    trail.nextWaiter = next;
                if (next == null)
                    lastWaiter = trail;
            }
            else
                trail = t;
            t = next;
        }
    }

    //将节点加入等待队列中。
    //返回一个新的等待节点。
    private Node addConditionWaiter() {
        Node t = lastWaiter;
        // 如果最后一个节点被cancledle,那么从首节点开始一次移除被cancled的节点
        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;
    }

    //移除或者转移节点,直到找到一个没有candled的节点或者节点为空。
    private void doSignal(Node first) {
        //first(非空)条件队列中的第一节点
        do {
            if ( (firstWaiter = first.nextWaiter) == null)
                lastWaiter = null;
            //断开与next的连接
            first.nextWaiter = null;
        } while (!transferForSignal(first) &&
                 (first = firstWaiter) != null);
                  // transferForSignal(first)返回false,说明节点被cancle了。
    }

    //将条件队列中所有节点全部移除并转移到条件队列中
    //参数first条件队列的头结点非空
    private void doSignalAll(Node first) {
        //将条件队列中的首尾节点置为null
        lastWaiter = firstWaiter = null;
        do {
            Node next = first.nextWaiter;
            //断开连接
            first.nextWaiter = null;
            transferForSignal(first);
            first = next;
        } while (first != null);
    }

2.protected方法

    //如果condition是指定的同步对象创建的,则返回true
    final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
        return sync == AbstractQueuedSynchronizer.this;
    }

    //查询是否有线程等待在当前condition上。
    //如果有线程等待,那么返回true。
    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;
    }

    //返回等待在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;
    }

    //返回可能等待在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;
    }

3.public方法

    //将等待时间最长的节点从条件队列转移到同步队列。
    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.用保存的同步状态作为参数,调用release,如果调用失败,
    //3.抛出IllegalMonitorStateException。
    //4.阻塞直到signal。
    //5.用保存的同步状态作为参数,调用acquire的acquireQueued版本重新获取同步状态。
    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();
    }

    //可中断的条件等待。
    //1.如果当前线程被中断了,那么抛出InterruptedException;
    //2.保存getState返回的锁的状态;
    //3.以保存的同步状态作为参数调用release,如果调用失败,
    //抛出IllegalMonitorStateException;
    //4.阻塞线程直到被signalled或者中断;
    //5.以保存的同步状态作为参数调用acquire的acquireQueued版本重新获取同步状态;
    //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;
        //如果节点的下一个节点为空,那么清理等待队列中的被cancelled的节点
        if (node.nextWaiter != null)
            unlinkCancelledWaiters();
        if (interruptMode != 0)
            reportInterruptAfterWait(interruptMode);
    }

    //指定时间的条件等待。
    //1.如果当前线程被中断了,InterruptedException;
    //2.保存getState返回的锁状态;
    //3.以保存的同步状态作为参数调用release,如果调用失败,
    //那么抛出IllegalMonitorStateException;
    //4.阻塞当前线程,直到被signal,被中断,或者等待时间到了;
    //5.以保存的同步状态调用acquireQueued为参数,重新获取同步状态。(??);
    //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返回的锁状态;
    //3.以保存的同步状态作为参数调用release,如果调用失败,
    //那么抛出IllegalMonitorStateException;
    //4.阻塞当前线程,直到被signal,被中断,或者等待时间到了;
    //5.以保存的同步状态调用acquireQueued为参数,重新获取同步状态(??);
    //6.在第4步阻塞的过程中,如果被中断,抛出InterruptedException;
    //7.如果在第4步阻塞等待的时候,时间到了,那么返回false,
    //否则,返回true。
    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;
    }

    //指定时间的条件等待。
    //1.如果当前线程被中断了,InterruptedException;
    //2.保存getState返回的锁状态;
    //3.以保存的同步状态作为参数调用release,如果调用失败,
    //那么抛出IllegalMonitorStateException;
    //4.阻塞当前线程,直到被signal,被中断,或者等待时间到了;
    //5.以保存的同步状态调用acquireQueued为参数,重新获取同步状态(??);
    //6.在第4步阻塞的过程中,如果被中断,抛出InterruptedException;
    //7.如果在第4步阻塞等待的时候,时间到了,那么返回false,
    //否则,返回true。
    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;
    }

嘻嘻,如果文章有错误的地方,麻烦小哥哥小姐姐帮忙指出改正,一起学习,一起交流。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容