首页 > 其他分享 >AbstractQueuedSynchronizer 的内部类 ConditionObject

AbstractQueuedSynchronizer 的内部类 ConditionObject

时间:2022-11-25 13:55:43浏览次数:30  
标签:node ConditionObject null 内部 InterruptedException Node link interruptMode Abstra

AbstractQueuedSynchronizer 的内部类 ConditionObject

Java 1.8.0_341

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

  //构造方法
  public ConditionObject() { }

  // 内部方法

  /**
   * Adds a new waiter to wait queue.
   * @return its new wait node
   * 添加一个新的进入等待队列
   * 返回新的等待节点 Node
   */
  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;
  }

  /**
   * Removes and transfers nodes until hit non-cancelled one or
   * null. Split out from signal in part to encourage compilers
   * to inline the case of no waiters.
   * @param first (non-null) the first node on condition queue
   * 
   * 唤醒一个等待线程
   */
  private void doSignal(Node first) {
    do {
      if ( (firstWaiter = first.nextWaiter) == null)
        lastWaiter = null;
      first.nextWaiter = null;
    } while (!transferForSignal(first) &&
             (first = firstWaiter) != null);
  }

  /**
   * Removes and transfers all nodes.
   * @param first (non-null) the first node on condition queue
   * 
   * 唤醒所有等待线程
   */
  private void doSignalAll(Node first) {
    lastWaiter = firstWaiter = null;
    do {
      Node next = first.nextWaiter;
      first.nextWaiter = null;
      transferForSignal(first);
      first = next;
    } while (first != null);
  }

  /**
   * Unlinks cancelled waiter nodes from condition queue.
   * Called only while holding lock. This is called when
   * cancellation occurred during condition wait, and upon
   * insertion of a new waiter when lastWaiter is seen to have
   * been cancelled. This method is needed to avoid garbage
   * retention in the absence of signals. So even though it may
   * require a full traversal, it comes into play only when
   * timeouts or cancellations occur in the absence of
   * signals. It traverses all nodes rather than stopping at a
   * particular target to unlink all pointers to garbage nodes
   * without requiring many re-traversals during cancellation
   * storms.
   *
   *
   */
  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;
    }
  }

  // 共有方法

  /**
   * Moves the longest-waiting thread, if one exists, from the
   * wait queue for this condition to the wait queue for the
   * owning lock.
   *
   * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
   *         returns {@code false}
   *
   * 唤醒一个等待线程。
   * 如果任何线程正在等待此条件,则选择一个线程进行唤醒。 那个线程必须在从await之前重新获取锁。
   */
  public final void signal() {
    if (!isHeldExclusively())
      throw new IllegalMonitorStateException();
    Node first = firstWaiter;
    if (first != null)
      doSignal(first);
  }

  /**
   * Moves all threads from the wait queue for this condition to
   * the wait queue for the owning lock.
   *
   * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
   *         returns {@code false}
   *
   * 唤醒所有等待线程。
   * 如果任何线程正在等待这个条件,那么它们都被唤醒。 每个线程必须重新获取锁,才能从await返回。
   */
  public final void signalAll() {
    if (!isHeldExclusively())
      throw new IllegalMonitorStateException();
    Node first = firstWaiter;
    if (first != null)
      doSignalAll(first);
  }

  /**
   * Implements uninterruptible condition wait.
   * <ol>
   * <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.
   * <li> Reacquire by invoking specialized version of
   *      {@link #acquire} with saved state as argument.
   * </ol>
   * 
   * 
   */
  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();
  }

 /*
  * For interruptible waits, we need to track whether to throw
  * InterruptedException, if interrupted while blocked on
  * condition, versus reinterrupt current thread, if
  * interrupted while blocked waiting to re-acquire.
  */

  /** 
   * Mode meaning to reinterrupt on exit from wait 
   * 模式的意思是在退出等待时重新中断
  */
  private static final int REINTERRUPT =  1;
  /** 
   * Mode meaning to throw InterruptedException on exit from wait 
   * 模式的意思是在退出等待时抛出InterruptedException
   */
  private static final int THROW_IE    = -1;

  /**
   * Checks for interrupt, returning THROW_IE if interrupted
   * before signalled, REINTERRUPT if after signalled, or
   * 0 if not interrupted.
   *
   * 检查中断,
   * 如果在发出信号之前中断,则返回THROW_IE;
   * 如果发出信号之后,则返回REINTERRUPT;
   * 如果未中断,则为0。
   */
  private int checkInterruptWhileWaiting(Node node) {
    return Thread.interrupted() ?
      (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :
    0;
  }

  /**
   * Throws InterruptedException, reinterrupts current thread, or
   * does nothing, depending on mode.
   *
   * 根据模式的不同,抛出InterruptedException、重新中断当前线程或什么都不做。
   */
  private void reportInterruptAfterWait(int interruptMode)
    throws InterruptedException {
    if (interruptMode == THROW_IE)
      throw new InterruptedException();
    else if (interruptMode == REINTERRUPT)
      selfInterrupt();
  }

  /**
   * Implements interruptible 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 or interrupted.
   * <li> Reacquire by invoking specialized version of
   *      {@link #acquire} with saved state as argument.
   * <li> If interrupted while blocked in step 4, throw InterruptedException.
   * </ol>
   *
   * 使当前线程等待,直到发出信号或{@linkplain Threadinterrupt interrupt}。
   * 1.如果当前线程被中断,则抛出InterruptedException。
   * 2.{@link getState}返回的保存锁定状态。
   * 3.使用保存状态作为参数调用{@link release},如果失败则抛出IllegalMonitorStateException。
   * 4.阻塞直到有信号或中断
   * 5.通过调用专门版本的{@link acquire},并将已保存的状态作为参数来重新获取。
   * 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);
  }

  /**
   * 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.
   * </ol>
   *
   * 使当前线程等待,直到发出信号或中断,或经过指定的等待时间。
   * 1.如果当前线程被中断,则抛出InterruptedException。
   * 2.{@link getState}返回的保存锁定状态。
   * 3.使用保存状态作为参数调用{@link release},如果失败则抛出IllegalMonitorStateException。
   * 4.阻塞直到有信号或中断,或超时
   * 5.通过调用专门版本的{@link acquire},并将已保存的状态作为参数来重新获取。
   * 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();
  }

  /**
   * Implements absolute 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 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>
   * 
   * 使当前线程等待,直到发出信号或中断,或经过指定的等待时间。
   * 该方法在行为上等同于:<pre> {@code awaitNanos(unit.toNanos(time)) > 0}</pre>
   */
  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;
  }

  //  support for instrumentation

  /**
   * Returns true if this condition was created by the given
   * synchronization object.
   *
   * @return {@code true} if owned
   *
   * 如果此条件是由给定的同步对象创建的,则返回true。
   */
  final boolean isOwnedBy(AbstractQueuedSynchronizer sync) {
    return sync == AbstractQueuedSynchronizer.this;
  }

  /**
   * Queries whether any threads are waiting on this condition.
   * Implements {@link AbstractQueuedSynchronizer#hasWaiters(ConditionObject)}.
   *
   * @return {@code true} if there are any waiting threads
   * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
   *         returns {@code false}
   *
   * 查询是否有线程在此条件下等待
   */
  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;
  }

  /**
   * Returns an estimate of the number of threads waiting on
   * this condition.
   * Implements {@link AbstractQueuedSynchronizer#getWaitQueueLength(ConditionObject)}.
   *
   * @return the estimated number of waiting threads
   * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
   *         returns {@code 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;
  }

  /**
   * Returns a collection containing those threads that may be
   * waiting on this Condition.
   * Implements {@link AbstractQueuedSynchronizer#getWaitingThreads(ConditionObject)}.
   *
   * @return the collection of threads
   * @throws IllegalMonitorStateException if {@link #isHeldExclusively}
   *         returns {@code false}
   *
   * 返回包含可能正在等待此条件的线程的集合。
   */
  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;
  }
}


标签:node,ConditionObject,null,内部,InterruptedException,Node,link,interruptMode,Abstra
From: https://www.cnblogs.com/coolyang/p/16924890.html

相关文章

  • “adb”不是内部或外部命令——解决方案
    “adb”不是内部或外部命令——解决方案 在AS(AndroidStudio简称AS)app真机测试中adb可以轻松找到安卓设备,ADB全称AndroidDebugBridge,用于Android设备进行交互,也可以......
  • 面向对象进阶(抽象、接口、内部类)
    ​ 抽象类:我们把没有方法体的方法称为抽象方法。Java语法规定,包含抽象方法的类就是抽象类。 抽象方法:没有方法体的方法。抽象类:包含抽象方法的类。 抽象类不......
  • 内部类混淆保持无效的办法
    -keepclassmembersclasscn.qssq666.safekeyboard.NKeyBoardTextField$SoftInputMode{*;}-keepclasscn.qssq666.safekeyboard.NKeyBoardTextField$SoftInputMode{*;}-kee......
  • SAP 事务 pdf! 生成PDF的内部实现和借鉴
    debug, pdf! 调用的是这个 bapi实现的 :SSFCOMP_PDF_PREVIEWSSFCOMP_PDF_PREVIEW又是通过 CONVERT_OTF来产生PDF的。screen0300,是一个加了webbrowser的屏幕,......
  • 内部类
    我们把一个类放在另一个类的内部定义,称为内部类(innerclass)。内部类的两个要点:内部类提供了更好的封装。只能让外部类直接访问,不允许同一个包中的其他类直接访问。......
  • Java 内部类有坑。。100 % 内存泄露!
    来源:https://knife.blog.csdn.net/article/details/124946774今天给大家分享一种,Java内部类使用不当导致的内存泄露问题,最终导致内存溢出!希望能够帮助到大家!简介「说明......
  • 基于springboot和vue的IT内部电脑报修服务系统设计与实现-计算机毕业设计源码+LW文档
    it内部设备服务系统设计与实现摘要it内部设备服务系统将传统的网络服务方式与最新的互联网技术相结合,使用方便快捷,有利于设备维修部门规范管理,提高网络维修部门的工作效......
  • 标准化接口对内部设计&外部通讯的影响
    问题与背景对外接口标准化、对内标准化、屏蔽算法实现、统一的访问模式,可枚举的返回类型…,这些词是经常见到的,但是在日常开发中,往往对其作用感受很少,但是这确实是有意义的,因......
  • Linux 中的内部命令和外部命令
    Linux中的内部命令和外部命令作者:Grey原文地址:博客园:Linux中的内部命令和外部命令CSDN:Linux中的内部命令和外部命令什么是bashshell?bashshell,就是一个程序,......
  • Effective C++ - 条款28 - 不要返回指向对象内部成分的handle
    这一条还是比较简单的,就是说不要返回指向对象内部成分的引用、指针等,即便这个引用可能声明为const(或指针指向了const对象),对内部成分做了保护,但仍有可能造成handle空悬(称为......