jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
changeset 34348 ba5c2f2fc9d7
parent 33674 566777f73c32
child 39725 9548f8d846e9
equal deleted inserted replaced
34347:4a17f9e90a0f 34348:ba5c2f2fc9d7
   920         return head != tail;
   920         return head != tail;
   921     }
   921     }
   922 
   922 
   923     /**
   923     /**
   924      * Queries whether any threads have ever contended to acquire this
   924      * Queries whether any threads have ever contended to acquire this
   925      * synchronizer; that is if an acquire method has ever blocked.
   925      * synchronizer; that is, if an acquire method has ever blocked.
   926      *
   926      *
   927      * <p>In this implementation, this operation returns in
   927      * <p>In this implementation, this operation returns in
   928      * constant time.
   928      * constant time.
   929      *
   929      *
   930      * @return {@code true} if there has ever been contention
   930      * @return {@code true} if there has ever been contention
   975          * is actually first node. If not, we continue on, safely
   975          * is actually first node. If not, we continue on, safely
   976          * traversing from tail back to head to find first,
   976          * traversing from tail back to head to find first,
   977          * guaranteeing termination.
   977          * guaranteeing termination.
   978          */
   978          */
   979 
   979 
   980         Node t = tail;
       
   981         Thread firstThread = null;
   980         Thread firstThread = null;
   982         while (t != null && t != head) {
   981         for (Node p = tail; p != null && p != head; p = p.prev) {
   983             Thread tt = t.thread;
   982             Thread t = p.thread;
   984             if (tt != null)
   983             if (t != null)
   985                 firstThread = tt;
   984                 firstThread = t;
   986             t = t.prev;
       
   987         }
   985         }
   988         return firstThread;
   986         return firstThread;
   989     }
   987     }
   990 
   988 
   991     /**
   989     /**
  1029      * than the current thread.
  1027      * than the current thread.
  1030      *
  1028      *
  1031      * <p>An invocation of this method is equivalent to (but may be
  1029      * <p>An invocation of this method is equivalent to (but may be
  1032      * more efficient than):
  1030      * more efficient than):
  1033      * <pre> {@code
  1031      * <pre> {@code
  1034      * getFirstQueuedThread() != Thread.currentThread() &&
  1032      * getFirstQueuedThread() != Thread.currentThread()
  1035      * hasQueuedThreads()}</pre>
  1033      *   && hasQueuedThreads()}</pre>
  1036      *
  1034      *
  1037      * <p>Note that because cancellations due to interrupts and
  1035      * <p>Note that because cancellations due to interrupts and
  1038      * timeouts may occur at any time, a {@code true} return does not
  1036      * timeouts may occur at any time, a {@code true} return does not
  1039      * guarantee that some other thread will acquire before the current
  1037      * guarantee that some other thread will acquire before the current
  1040      * thread.  Likewise, it is possible for another thread to win a
  1038      * thread.  Likewise, it is possible for another thread to win a
  1633             while (!isOnSyncQueue(node)) {
  1631             while (!isOnSyncQueue(node)) {
  1634                 if (nanosTimeout <= 0L) {
  1632                 if (nanosTimeout <= 0L) {
  1635                     transferAfterCancelledWait(node);
  1633                     transferAfterCancelledWait(node);
  1636                     break;
  1634                     break;
  1637                 }
  1635                 }
  1638                 if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD)
  1636                 if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
  1639                     LockSupport.parkNanos(this, nanosTimeout);
  1637                     LockSupport.parkNanos(this, nanosTimeout);
  1640                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
  1638                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
  1641                     break;
  1639                     break;
  1642                 nanosTimeout = deadline - System.nanoTime();
  1640                 nanosTimeout = deadline - System.nanoTime();
  1643             }
  1641             }
  1721             while (!isOnSyncQueue(node)) {
  1719             while (!isOnSyncQueue(node)) {
  1722                 if (nanosTimeout <= 0L) {
  1720                 if (nanosTimeout <= 0L) {
  1723                     timedout = transferAfterCancelledWait(node);
  1721                     timedout = transferAfterCancelledWait(node);
  1724                     break;
  1722                     break;
  1725                 }
  1723                 }
  1726                 if (nanosTimeout >= SPIN_FOR_TIMEOUT_THRESHOLD)
  1724                 if (nanosTimeout > SPIN_FOR_TIMEOUT_THRESHOLD)
  1727                     LockSupport.parkNanos(this, nanosTimeout);
  1725                     LockSupport.parkNanos(this, nanosTimeout);
  1728                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
  1726                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
  1729                     break;
  1727                     break;
  1730                 nanosTimeout = deadline - System.nanoTime();
  1728                 nanosTimeout = deadline - System.nanoTime();
  1731             }
  1729             }
  1845 
  1843 
  1846     /**
  1844     /**
  1847      * Initializes head and tail fields on first contention.
  1845      * Initializes head and tail fields on first contention.
  1848      */
  1846      */
  1849     private final void initializeSyncQueue() {
  1847     private final void initializeSyncQueue() {
  1850         if (U.compareAndSwapObject(this, HEAD, null, new Node()))
  1848         Node h;
  1851             tail = head;
  1849         if (U.compareAndSwapObject(this, HEAD, null, (h = new Node())))
       
  1850             tail = h;
  1852     }
  1851     }
  1853 
  1852 
  1854     /**
  1853     /**
  1855      * CASes tail field.
  1854      * CASes tail field.
  1856      */
  1855      */