src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java

Print this page




  22  * questions.
  23  */
  24 
  25 /*
  26  * This file is available under and governed by the GNU General Public
  27  * License version 2 only, as published by the Free Software Foundation.
  28  * However, the following notice accompanied the original version of this
  29  * file:
  30  *
  31  * Written by Doug Lea with assistance from members of JCP JSR-166
  32  * Expert Group and released to the public domain, as explained at
  33  * http://creativecommons.org/publicdomain/zero/1.0/
  34  */
  35 
  36 package java.util.concurrent.locks;
  37 
  38 import java.util.ArrayList;
  39 import java.util.Collection;
  40 import java.util.Date;
  41 import java.util.concurrent.TimeUnit;

  42 
  43 /**
  44  * Provides a framework for implementing blocking locks and related
  45  * synchronizers (semaphores, events, etc) that rely on
  46  * first-in-first-out (FIFO) wait queues.  This class is designed to
  47  * be a useful basis for most kinds of synchronizers that rely on a
  48  * single atomic {@code int} value to represent state. Subclasses
  49  * must define the protected methods that change this state, and which
  50  * define what that state means in terms of this object being acquired
  51  * or released.  Given these, the other methods in this class carry
  52  * out all queuing and blocking mechanics. Subclasses can maintain
  53  * other state fields, but only the atomically updated {@code int}
  54  * value manipulated using methods {@link #getState}, {@link
  55  * #setState} and {@link #compareAndSetState} is tracked with respect
  56  * to synchronization.
  57  *
  58  * <p>Subclasses should be defined as non-public internal helper
  59  * classes that are used to implement the synchronization properties
  60  * of their enclosing class.  Class
  61  * {@code AbstractQueuedSynchronizer} does not implement any


 869         return Thread.interrupted();
 870     }
 871 
 872     /*
 873      * Various flavors of acquire, varying in exclusive/shared and
 874      * control modes.  Each is mostly the same, but annoyingly
 875      * different.  Only a little bit of factoring is possible due to
 876      * interactions of exception mechanics (including ensuring that we
 877      * cancel if tryAcquire throws exception) and other control, at
 878      * least not without hurting performance too much.
 879      */
 880 
 881     /**
 882      * Acquires in exclusive uninterruptible mode for thread already in
 883      * queue. Used by condition wait methods as well as acquire.
 884      *
 885      * @param node the node
 886      * @param arg the acquire argument
 887      * @return {@code true} if interrupted while waiting
 888      */

 889     final boolean acquireQueued(final Node node, int arg) {
 890         try {
 891             boolean interrupted = false;
 892             for (;;) {
 893                 final Node p = node.predecessor();
 894                 if (p == head && tryAcquire(arg)) {
 895                     setHead(node);
 896                     p.next = null; // help GC
 897                     return interrupted;
 898                 }
 899                 if (shouldParkAfterFailedAcquire(p, node) &&
 900                     parkAndCheckInterrupt())
 901                     interrupted = true;
 902             }
 903         } catch (Throwable t) {
 904             cancelAcquire(node);
 905             throw t;
 906         }
 907     }
 908 


1201      * @return {@code true} if synchronization is held exclusively;
1202      *         {@code false} otherwise
1203      * @throws UnsupportedOperationException if conditions are not supported
1204      */
1205     protected boolean isHeldExclusively() {
1206         throw new UnsupportedOperationException();
1207     }
1208 
1209     /**
1210      * Acquires in exclusive mode, ignoring interrupts.  Implemented
1211      * by invoking at least once {@link #tryAcquire},
1212      * returning on success.  Otherwise the thread is queued, possibly
1213      * repeatedly blocking and unblocking, invoking {@link
1214      * #tryAcquire} until success.  This method can be used
1215      * to implement method {@link Lock#lock}.
1216      *
1217      * @param arg the acquire argument.  This value is conveyed to
1218      *        {@link #tryAcquire} but is otherwise uninterpreted and
1219      *        can represent anything you like.
1220      */

1221     public final void acquire(int arg) {
1222         if (!tryAcquire(arg) &&
1223             acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
1224             selfInterrupt();
1225     }
1226 
1227     /**
1228      * Acquires in exclusive mode, aborting if interrupted.
1229      * Implemented by first checking interrupt status, then invoking
1230      * at least once {@link #tryAcquire}, returning on
1231      * success.  Otherwise the thread is queued, possibly repeatedly
1232      * blocking and unblocking, invoking {@link #tryAcquire}
1233      * until success or the thread is interrupted.  This method can be
1234      * used to implement method {@link Lock#lockInterruptibly}.
1235      *
1236      * @param arg the acquire argument.  This value is conveyed to
1237      *        {@link #tryAcquire} but is otherwise uninterpreted and
1238      *        can represent anything you like.
1239      * @throws InterruptedException if the current thread is interrupted
1240      */


1264      * @throws InterruptedException if the current thread is interrupted
1265      */
1266     public final boolean tryAcquireNanos(int arg, long nanosTimeout)
1267             throws InterruptedException {
1268         if (Thread.interrupted())
1269             throw new InterruptedException();
1270         return tryAcquire(arg) ||
1271             doAcquireNanos(arg, nanosTimeout);
1272     }
1273 
1274     /**
1275      * Releases in exclusive mode.  Implemented by unblocking one or
1276      * more threads if {@link #tryRelease} returns true.
1277      * This method can be used to implement method {@link Lock#unlock}.
1278      *
1279      * @param arg the release argument.  This value is conveyed to
1280      *        {@link #tryRelease} but is otherwise uninterpreted and
1281      *        can represent anything you like.
1282      * @return the value returned from {@link #tryRelease}
1283      */

1284     public final boolean release(int arg) {
1285         if (tryRelease(arg)) {
1286             Node h = head;
1287             if (h != null && h.waitStatus != 0)
1288                 unparkSuccessor(h);
1289             return true;
1290         }
1291         return false;
1292     }
1293 
1294     /**
1295      * Acquires in shared mode, ignoring interrupts.  Implemented by
1296      * first invoking at least once {@link #tryAcquireShared},
1297      * returning on success.  Otherwise the thread is queued, possibly
1298      * repeatedly blocking and unblocking, invoking {@link
1299      * #tryAcquireShared} until success.
1300      *
1301      * @param arg the acquire argument.  This value is conveyed to
1302      *        {@link #tryAcquireShared} but is otherwise uninterpreted
1303      *        and can represent anything you like.


1344      * @return {@code true} if acquired; {@code false} if timed out
1345      * @throws InterruptedException if the current thread is interrupted
1346      */
1347     public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
1348             throws InterruptedException {
1349         if (Thread.interrupted())
1350             throw new InterruptedException();
1351         return tryAcquireShared(arg) >= 0 ||
1352             doAcquireSharedNanos(arg, nanosTimeout);
1353     }
1354 
1355     /**
1356      * Releases in shared mode.  Implemented by unblocking one or more
1357      * threads if {@link #tryReleaseShared} returns true.
1358      *
1359      * @param arg the release argument.  This value is conveyed to
1360      *        {@link #tryReleaseShared} but is otherwise uninterpreted
1361      *        and can represent anything you like.
1362      * @return the value returned from {@link #tryReleaseShared}
1363      */

1364     public final boolean releaseShared(int arg) {
1365         if (tryReleaseShared(arg)) {
1366             doReleaseShared();
1367             return true;
1368         }
1369         return false;
1370     }
1371 
1372     // Queue inspection methods
1373 
1374     /**
1375      * Queries whether any threads are waiting to acquire. Note that
1376      * because cancellations due to interrupts and timeouts may occur
1377      * at any time, a {@code true} return does not guarantee that any
1378      * other thread will ever acquire.
1379      *
1380      * <p>In this implementation, this operation returns in
1381      * constant time.
1382      *
1383      * @return {@code true} if there may be other threads waiting to acquire




  22  * questions.
  23  */
  24 
  25 /*
  26  * This file is available under and governed by the GNU General Public
  27  * License version 2 only, as published by the Free Software Foundation.
  28  * However, the following notice accompanied the original version of this
  29  * file:
  30  *
  31  * Written by Doug Lea with assistance from members of JCP JSR-166
  32  * Expert Group and released to the public domain, as explained at
  33  * http://creativecommons.org/publicdomain/zero/1.0/
  34  */
  35 
  36 package java.util.concurrent.locks;
  37 
  38 import java.util.ArrayList;
  39 import java.util.Collection;
  40 import java.util.Date;
  41 import java.util.concurrent.TimeUnit;
  42 import jdk.internal.vm.annotation.ReservedStackAccess;
  43 
  44 /**
  45  * Provides a framework for implementing blocking locks and related
  46  * synchronizers (semaphores, events, etc) that rely on
  47  * first-in-first-out (FIFO) wait queues.  This class is designed to
  48  * be a useful basis for most kinds of synchronizers that rely on a
  49  * single atomic {@code int} value to represent state. Subclasses
  50  * must define the protected methods that change this state, and which
  51  * define what that state means in terms of this object being acquired
  52  * or released.  Given these, the other methods in this class carry
  53  * out all queuing and blocking mechanics. Subclasses can maintain
  54  * other state fields, but only the atomically updated {@code int}
  55  * value manipulated using methods {@link #getState}, {@link
  56  * #setState} and {@link #compareAndSetState} is tracked with respect
  57  * to synchronization.
  58  *
  59  * <p>Subclasses should be defined as non-public internal helper
  60  * classes that are used to implement the synchronization properties
  61  * of their enclosing class.  Class
  62  * {@code AbstractQueuedSynchronizer} does not implement any


 870         return Thread.interrupted();
 871     }
 872 
 873     /*
 874      * Various flavors of acquire, varying in exclusive/shared and
 875      * control modes.  Each is mostly the same, but annoyingly
 876      * different.  Only a little bit of factoring is possible due to
 877      * interactions of exception mechanics (including ensuring that we
 878      * cancel if tryAcquire throws exception) and other control, at
 879      * least not without hurting performance too much.
 880      */
 881 
 882     /**
 883      * Acquires in exclusive uninterruptible mode for thread already in
 884      * queue. Used by condition wait methods as well as acquire.
 885      *
 886      * @param node the node
 887      * @param arg the acquire argument
 888      * @return {@code true} if interrupted while waiting
 889      */
 890     @ReservedStackAccess
 891     final boolean acquireQueued(final Node node, int arg) {
 892         try {
 893             boolean interrupted = false;
 894             for (;;) {
 895                 final Node p = node.predecessor();
 896                 if (p == head && tryAcquire(arg)) {
 897                     setHead(node);
 898                     p.next = null; // help GC
 899                     return interrupted;
 900                 }
 901                 if (shouldParkAfterFailedAcquire(p, node) &&
 902                     parkAndCheckInterrupt())
 903                     interrupted = true;
 904             }
 905         } catch (Throwable t) {
 906             cancelAcquire(node);
 907             throw t;
 908         }
 909     }
 910 


1203      * @return {@code true} if synchronization is held exclusively;
1204      *         {@code false} otherwise
1205      * @throws UnsupportedOperationException if conditions are not supported
1206      */
1207     protected boolean isHeldExclusively() {
1208         throw new UnsupportedOperationException();
1209     }
1210 
1211     /**
1212      * Acquires in exclusive mode, ignoring interrupts.  Implemented
1213      * by invoking at least once {@link #tryAcquire},
1214      * returning on success.  Otherwise the thread is queued, possibly
1215      * repeatedly blocking and unblocking, invoking {@link
1216      * #tryAcquire} until success.  This method can be used
1217      * to implement method {@link Lock#lock}.
1218      *
1219      * @param arg the acquire argument.  This value is conveyed to
1220      *        {@link #tryAcquire} but is otherwise uninterpreted and
1221      *        can represent anything you like.
1222      */
1223     @ReservedStackAccess
1224     public final void acquire(int arg) {
1225         if (!tryAcquire(arg) &&
1226             acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
1227             selfInterrupt();
1228     }
1229 
1230     /**
1231      * Acquires in exclusive mode, aborting if interrupted.
1232      * Implemented by first checking interrupt status, then invoking
1233      * at least once {@link #tryAcquire}, returning on
1234      * success.  Otherwise the thread is queued, possibly repeatedly
1235      * blocking and unblocking, invoking {@link #tryAcquire}
1236      * until success or the thread is interrupted.  This method can be
1237      * used to implement method {@link Lock#lockInterruptibly}.
1238      *
1239      * @param arg the acquire argument.  This value is conveyed to
1240      *        {@link #tryAcquire} but is otherwise uninterpreted and
1241      *        can represent anything you like.
1242      * @throws InterruptedException if the current thread is interrupted
1243      */


1267      * @throws InterruptedException if the current thread is interrupted
1268      */
1269     public final boolean tryAcquireNanos(int arg, long nanosTimeout)
1270             throws InterruptedException {
1271         if (Thread.interrupted())
1272             throw new InterruptedException();
1273         return tryAcquire(arg) ||
1274             doAcquireNanos(arg, nanosTimeout);
1275     }
1276 
1277     /**
1278      * Releases in exclusive mode.  Implemented by unblocking one or
1279      * more threads if {@link #tryRelease} returns true.
1280      * This method can be used to implement method {@link Lock#unlock}.
1281      *
1282      * @param arg the release argument.  This value is conveyed to
1283      *        {@link #tryRelease} but is otherwise uninterpreted and
1284      *        can represent anything you like.
1285      * @return the value returned from {@link #tryRelease}
1286      */
1287     @ReservedStackAccess
1288     public final boolean release(int arg) {
1289         if (tryRelease(arg)) {
1290             Node h = head;
1291             if (h != null && h.waitStatus != 0)
1292                 unparkSuccessor(h);
1293             return true;
1294         }
1295         return false;
1296     }
1297 
1298     /**
1299      * Acquires in shared mode, ignoring interrupts.  Implemented by
1300      * first invoking at least once {@link #tryAcquireShared},
1301      * returning on success.  Otherwise the thread is queued, possibly
1302      * repeatedly blocking and unblocking, invoking {@link
1303      * #tryAcquireShared} until success.
1304      *
1305      * @param arg the acquire argument.  This value is conveyed to
1306      *        {@link #tryAcquireShared} but is otherwise uninterpreted
1307      *        and can represent anything you like.


1348      * @return {@code true} if acquired; {@code false} if timed out
1349      * @throws InterruptedException if the current thread is interrupted
1350      */
1351     public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout)
1352             throws InterruptedException {
1353         if (Thread.interrupted())
1354             throw new InterruptedException();
1355         return tryAcquireShared(arg) >= 0 ||
1356             doAcquireSharedNanos(arg, nanosTimeout);
1357     }
1358 
1359     /**
1360      * Releases in shared mode.  Implemented by unblocking one or more
1361      * threads if {@link #tryReleaseShared} returns true.
1362      *
1363      * @param arg the release argument.  This value is conveyed to
1364      *        {@link #tryReleaseShared} but is otherwise uninterpreted
1365      *        and can represent anything you like.
1366      * @return the value returned from {@link #tryReleaseShared}
1367      */
1368     @ReservedStackAccess
1369     public final boolean releaseShared(int arg) {
1370         if (tryReleaseShared(arg)) {
1371             doReleaseShared();
1372             return true;
1373         }
1374         return false;
1375     }
1376 
1377     // Queue inspection methods
1378 
1379     /**
1380      * Queries whether any threads are waiting to acquire. Note that
1381      * because cancellations due to interrupts and timeouts may occur
1382      * at any time, a {@code true} return does not guarantee that any
1383      * other thread will ever acquire.
1384      *
1385      * <p>In this implementation, this operation returns in
1386      * constant time.
1387      *
1388      * @return {@code true} if there may be other threads waiting to acquire