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

Print this page




  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  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.Collection;
  39 import java.util.concurrent.TimeUnit;

  40 
  41 /**
  42  * A reentrant mutual exclusion {@link Lock} with the same basic
  43  * behavior and semantics as the implicit monitor lock accessed using
  44  * {@code synchronized} methods and statements, but with extended
  45  * capabilities.
  46  *
  47  * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
  48  * successfully locking, but not yet unlocking it. A thread invoking
  49  * {@code lock} will return, successfully acquiring the lock, when
  50  * the lock is not owned by another thread. The method will return
  51  * immediately if the current thread already owns the lock. This can
  52  * be checked using methods {@link #isHeldByCurrentThread}, and {@link
  53  * #getHoldCount}.
  54  *
  55  * <p>The constructor for this class accepts an optional
  56  * <em>fairness</em> parameter.  When set {@code true}, under
  57  * contention, locks favor granting access to the longest-waiting
  58  * thread.  Otherwise this lock does not guarantee any particular
  59  * access order.  Programs using fair locks accessed by many threads


 110     private final Sync sync;
 111 
 112     /**
 113      * Base of synchronization control for this lock. Subclassed
 114      * into fair and nonfair versions below. Uses AQS state to
 115      * represent the number of holds on the lock.
 116      */
 117     abstract static class Sync extends AbstractQueuedSynchronizer {
 118         private static final long serialVersionUID = -5179523762034025860L;
 119 
 120         /**
 121          * Performs {@link Lock#lock}. The main reason for subclassing
 122          * is to allow fast path for nonfair version.
 123          */
 124         abstract void lock();
 125 
 126         /**
 127          * Performs non-fair tryLock.  tryAcquire is implemented in
 128          * subclasses, but both need nonfair try for trylock method.
 129          */

 130         final boolean nonfairTryAcquire(int acquires) {
 131             final Thread current = Thread.currentThread();
 132             int c = getState();
 133             if (c == 0) {
 134                 if (compareAndSetState(0, acquires)) {
 135                     setExclusiveOwnerThread(current);
 136                     return true;
 137                 }
 138             }
 139             else if (current == getExclusiveOwnerThread()) {
 140                 int nextc = c + acquires;
 141                 if (nextc < 0) // overflow
 142                     throw new Error("Maximum lock count exceeded");
 143                 setState(nextc);
 144                 return true;
 145             }
 146             return false;
 147         }
 148 

 149         protected final boolean tryRelease(int releases) {
 150             int c = getState() - releases;
 151             if (Thread.currentThread() != getExclusiveOwnerThread())
 152                 throw new IllegalMonitorStateException();
 153             boolean free = false;
 154             if (c == 0) {
 155                 free = true;
 156                 setExclusiveOwnerThread(null);
 157             }
 158             setState(c);
 159             return free;
 160         }
 161 
 162         protected final boolean isHeldExclusively() {
 163             // While we must in general read state before owner,
 164             // we don't need to do so to check if current thread is owner
 165             return getExclusiveOwnerThread() == Thread.currentThread();
 166         }
 167 
 168         final ConditionObject newCondition() {


 186         /**
 187          * Reconstitutes the instance from a stream (that is, deserializes it).
 188          */
 189         private void readObject(java.io.ObjectInputStream s)
 190             throws java.io.IOException, ClassNotFoundException {
 191             s.defaultReadObject();
 192             setState(0); // reset to unlocked state
 193         }
 194     }
 195 
 196     /**
 197      * Sync object for non-fair locks
 198      */
 199     static final class NonfairSync extends Sync {
 200         private static final long serialVersionUID = 7316153563782823691L;
 201 
 202         /**
 203          * Performs lock.  Try immediate barge, backing up to normal
 204          * acquire on failure.
 205          */

 206         final void lock() {
 207             if (compareAndSetState(0, 1))
 208                 setExclusiveOwnerThread(Thread.currentThread());
 209             else
 210                 acquire(1);
 211         }
 212 
 213         protected final boolean tryAcquire(int acquires) {
 214             return nonfairTryAcquire(acquires);
 215         }
 216     }
 217 
 218     /**
 219      * Sync object for fair locks
 220      */
 221     static final class FairSync extends Sync {
 222         private static final long serialVersionUID = -3000897897090466540L;
 223 
 224         final void lock() {
 225             acquire(1);
 226         }
 227 
 228         /**
 229          * Fair version of tryAcquire.  Don't grant access unless
 230          * recursive call or no waiters or is first.
 231          */

 232         protected final boolean tryAcquire(int acquires) {
 233             final Thread current = Thread.currentThread();
 234             int c = getState();
 235             if (c == 0) {
 236                 if (!hasQueuedPredecessors() &&
 237                     compareAndSetState(0, acquires)) {
 238                     setExclusiveOwnerThread(current);
 239                     return true;
 240                 }
 241             }
 242             else if (current == getExclusiveOwnerThread()) {
 243                 int nextc = c + acquires;
 244                 if (nextc < 0)
 245                     throw new Error("Maximum lock count exceeded");
 246                 setState(nextc);
 247                 return true;
 248             }
 249             return false;
 250         }
 251     }




  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  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.Collection;
  39 import java.util.concurrent.TimeUnit;
  40 import jdk.internal.vm.annotation.ReservedStackAccess;
  41 
  42 /**
  43  * A reentrant mutual exclusion {@link Lock} with the same basic
  44  * behavior and semantics as the implicit monitor lock accessed using
  45  * {@code synchronized} methods and statements, but with extended
  46  * capabilities.
  47  *
  48  * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
  49  * successfully locking, but not yet unlocking it. A thread invoking
  50  * {@code lock} will return, successfully acquiring the lock, when
  51  * the lock is not owned by another thread. The method will return
  52  * immediately if the current thread already owns the lock. This can
  53  * be checked using methods {@link #isHeldByCurrentThread}, and {@link
  54  * #getHoldCount}.
  55  *
  56  * <p>The constructor for this class accepts an optional
  57  * <em>fairness</em> parameter.  When set {@code true}, under
  58  * contention, locks favor granting access to the longest-waiting
  59  * thread.  Otherwise this lock does not guarantee any particular
  60  * access order.  Programs using fair locks accessed by many threads


 111     private final Sync sync;
 112 
 113     /**
 114      * Base of synchronization control for this lock. Subclassed
 115      * into fair and nonfair versions below. Uses AQS state to
 116      * represent the number of holds on the lock.
 117      */
 118     abstract static class Sync extends AbstractQueuedSynchronizer {
 119         private static final long serialVersionUID = -5179523762034025860L;
 120 
 121         /**
 122          * Performs {@link Lock#lock}. The main reason for subclassing
 123          * is to allow fast path for nonfair version.
 124          */
 125         abstract void lock();
 126 
 127         /**
 128          * Performs non-fair tryLock.  tryAcquire is implemented in
 129          * subclasses, but both need nonfair try for trylock method.
 130          */
 131         @ReservedStackAccess
 132         final boolean nonfairTryAcquire(int acquires) {
 133             final Thread current = Thread.currentThread();
 134             int c = getState();
 135             if (c == 0) {
 136                 if (compareAndSetState(0, acquires)) {
 137                     setExclusiveOwnerThread(current);
 138                     return true;
 139                 }
 140             }
 141             else if (current == getExclusiveOwnerThread()) {
 142                 int nextc = c + acquires;
 143                 if (nextc < 0) // overflow
 144                     throw new Error("Maximum lock count exceeded");
 145                 setState(nextc);
 146                 return true;
 147             }
 148             return false;
 149         }
 150 
 151         @ReservedStackAccess
 152         protected final boolean tryRelease(int releases) {
 153             int c = getState() - releases;
 154             if (Thread.currentThread() != getExclusiveOwnerThread())
 155                 throw new IllegalMonitorStateException();
 156             boolean free = false;
 157             if (c == 0) {
 158                 free = true;
 159                 setExclusiveOwnerThread(null);
 160             }
 161             setState(c);
 162             return free;
 163         }
 164 
 165         protected final boolean isHeldExclusively() {
 166             // While we must in general read state before owner,
 167             // we don't need to do so to check if current thread is owner
 168             return getExclusiveOwnerThread() == Thread.currentThread();
 169         }
 170 
 171         final ConditionObject newCondition() {


 189         /**
 190          * Reconstitutes the instance from a stream (that is, deserializes it).
 191          */
 192         private void readObject(java.io.ObjectInputStream s)
 193             throws java.io.IOException, ClassNotFoundException {
 194             s.defaultReadObject();
 195             setState(0); // reset to unlocked state
 196         }
 197     }
 198 
 199     /**
 200      * Sync object for non-fair locks
 201      */
 202     static final class NonfairSync extends Sync {
 203         private static final long serialVersionUID = 7316153563782823691L;
 204 
 205         /**
 206          * Performs lock.  Try immediate barge, backing up to normal
 207          * acquire on failure.
 208          */
 209         @ReservedStackAccess
 210         final void lock() {
 211             if (compareAndSetState(0, 1))
 212                 setExclusiveOwnerThread(Thread.currentThread());
 213             else
 214                 acquire(1);
 215         }
 216 
 217         protected final boolean tryAcquire(int acquires) {
 218             return nonfairTryAcquire(acquires);
 219         }
 220     }
 221 
 222     /**
 223      * Sync object for fair locks
 224      */
 225     static final class FairSync extends Sync {
 226         private static final long serialVersionUID = -3000897897090466540L;
 227 
 228         final void lock() {
 229             acquire(1);
 230         }
 231 
 232         /**
 233          * Fair version of tryAcquire.  Don't grant access unless
 234          * recursive call or no waiters or is first.
 235          */
 236         @ReservedStackAccess
 237         protected final boolean tryAcquire(int acquires) {
 238             final Thread current = Thread.currentThread();
 239             int c = getState();
 240             if (c == 0) {
 241                 if (!hasQueuedPredecessors() &&
 242                     compareAndSetState(0, acquires)) {
 243                     setExclusiveOwnerThread(current);
 244                     return true;
 245                 }
 246             }
 247             else if (current == getExclusiveOwnerThread()) {
 248                 int nextc = c + acquires;
 249                 if (nextc < 0)
 250                     throw new Error("Maximum lock count exceeded");
 251                 setState(nextc);
 252                 return true;
 253             }
 254             return false;
 255         }
 256     }