GNU Classpath (0.98) | |
Frames | No Frames |
1: /* 2: * Written by Doug Lea with assistance from members of JCP JSR-166 3: * Expert Group and released to the public domain, as explained at 4: * http://creativecommons.org/licenses/publicdomain 5: */ 6: 7: package java.util.concurrent.locks; 8: import java.util.*; 9: import java.util.concurrent.*; 10: import java.util.concurrent.atomic.*; 11: 12: /** 13: * A reentrant mutual exclusion {@link Lock} with the same basic 14: * behavior and semantics as the implicit monitor lock accessed using 15: * {@code synchronized} methods and statements, but with extended 16: * capabilities. 17: * 18: * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last 19: * successfully locking, but not yet unlocking it. A thread invoking 20: * {@code lock} will return, successfully acquiring the lock, when 21: * the lock is not owned by another thread. The method will return 22: * immediately if the current thread already owns the lock. This can 23: * be checked using methods {@link #isHeldByCurrentThread}, and {@link 24: * #getHoldCount}. 25: * 26: * <p>The constructor for this class accepts an optional 27: * <em>fairness</em> parameter. When set {@code true}, under 28: * contention, locks favor granting access to the longest-waiting 29: * thread. Otherwise this lock does not guarantee any particular 30: * access order. Programs using fair locks accessed by many threads 31: * may display lower overall throughput (i.e., are slower; often much 32: * slower) than those using the default setting, but have smaller 33: * variances in times to obtain locks and guarantee lack of 34: * starvation. Note however, that fairness of locks does not guarantee 35: * fairness of thread scheduling. Thus, one of many threads using a 36: * fair lock may obtain it multiple times in succession while other 37: * active threads are not progressing and not currently holding the 38: * lock. 39: * Also note that the untimed {@link #tryLock() tryLock} method does not 40: * honor the fairness setting. It will succeed if the lock 41: * is available even if other threads are waiting. 42: * 43: * <p>It is recommended practice to <em>always</em> immediately 44: * follow a call to {@code lock} with a {@code try} block, most 45: * typically in a before/after construction such as: 46: * 47: * <pre> 48: * class X { 49: * private final ReentrantLock lock = new ReentrantLock(); 50: * // ... 51: * 52: * public void m() { 53: * lock.lock(); // block until condition holds 54: * try { 55: * // ... method body 56: * } finally { 57: * lock.unlock() 58: * } 59: * } 60: * } 61: * </pre> 62: * 63: * <p>In addition to implementing the {@link Lock} interface, this 64: * class defines methods {@code isLocked} and 65: * {@code getLockQueueLength}, as well as some associated 66: * {@code protected} access methods that may be useful for 67: * instrumentation and monitoring. 68: * 69: * <p>Serialization of this class behaves in the same way as built-in 70: * locks: a deserialized lock is in the unlocked state, regardless of 71: * its state when serialized. 72: * 73: * <p>This lock supports a maximum of 2147483647 recursive locks by 74: * the same thread. Attempts to exceed this limit result in 75: * {@link Error} throws from locking methods. 76: * 77: * @since 1.5 78: * @author Doug Lea 79: */ 80: public class ReentrantLock implements Lock, java.io.Serializable { 81: private static final long serialVersionUID = 7373984872572414699L; 82: /** Synchronizer providing all implementation mechanics */ 83: private final Sync sync; 84: 85: /** 86: * Base of synchronization control for this lock. Subclassed 87: * into fair and nonfair versions below. Uses AQS state to 88: * represent the number of holds on the lock. 89: */ 90: static abstract class Sync extends AbstractQueuedSynchronizer { 91: private static final long serialVersionUID = -5179523762034025860L; 92: 93: /** 94: * Performs {@link Lock#lock}. The main reason for subclassing 95: * is to allow fast path for nonfair version. 96: */ 97: abstract void lock(); 98: 99: /** 100: * Performs non-fair tryLock. tryAcquire is 101: * implemented in subclasses, but both need nonfair 102: * try for trylock method. 103: */ 104: final boolean nonfairTryAcquire(int acquires) { 105: final Thread current = Thread.currentThread(); 106: int c = getState(); 107: if (c == 0) { 108: if (compareAndSetState(0, acquires)) { 109: setExclusiveOwnerThread(current); 110: return true; 111: } 112: } 113: else if (current == getExclusiveOwnerThread()) { 114: int nextc = c + acquires; 115: if (nextc < 0) // overflow 116: throw new Error("Maximum lock count exceeded"); 117: setState(nextc); 118: return true; 119: } 120: return false; 121: } 122: 123: protected final boolean tryRelease(int releases) { 124: int c = getState() - releases; 125: if (Thread.currentThread() != getExclusiveOwnerThread()) 126: throw new IllegalMonitorStateException(); 127: boolean free = false; 128: if (c == 0) { 129: free = true; 130: setExclusiveOwnerThread(null); 131: } 132: setState(c); 133: return free; 134: } 135: 136: protected final boolean isHeldExclusively() { 137: // While we must in general read state before owner, 138: // we don't need to do so to check if current thread is owner 139: return getExclusiveOwnerThread() == Thread.currentThread(); 140: } 141: 142: final ConditionObject newCondition() { 143: return new ConditionObject(); 144: } 145: 146: // Methods relayed from outer class 147: 148: final Thread getOwner() { 149: return getState() == 0 ? null : getExclusiveOwnerThread(); 150: } 151: 152: final int getHoldCount() { 153: return isHeldExclusively() ? getState() : 0; 154: } 155: 156: final boolean isLocked() { 157: return getState() != 0; 158: } 159: 160: /** 161: * Reconstitutes this lock instance from a stream. 162: * @param s the stream 163: */ 164: private void readObject(java.io.ObjectInputStream s) 165: throws java.io.IOException, ClassNotFoundException { 166: s.defaultReadObject(); 167: setState(0); // reset to unlocked state 168: } 169: } 170: 171: /** 172: * Sync object for non-fair locks 173: */ 174: final static class NonfairSync extends Sync { 175: private static final long serialVersionUID = 7316153563782823691L; 176: 177: /** 178: * Performs lock. Try immediate barge, backing up to normal 179: * acquire on failure. 180: */ 181: final void lock() { 182: if (compareAndSetState(0, 1)) 183: setExclusiveOwnerThread(Thread.currentThread()); 184: else 185: acquire(1); 186: } 187: 188: protected final boolean tryAcquire(int acquires) { 189: return nonfairTryAcquire(acquires); 190: } 191: } 192: 193: /** 194: * Sync object for fair locks 195: */ 196: final static class FairSync extends Sync { 197: private static final long serialVersionUID = -3000897897090466540L; 198: 199: final void lock() { 200: acquire(1); 201: } 202: 203: /** 204: * Fair version of tryAcquire. Don't grant access unless 205: * recursive call or no waiters or is first. 206: */ 207: protected final boolean tryAcquire(int acquires) { 208: final Thread current = Thread.currentThread(); 209: int c = getState(); 210: if (c == 0) { 211: if (isFirst(current) && 212: compareAndSetState(0, acquires)) { 213: setExclusiveOwnerThread(current); 214: return true; 215: } 216: } 217: else if (current == getExclusiveOwnerThread()) { 218: int nextc = c + acquires; 219: if (nextc < 0) 220: throw new Error("Maximum lock count exceeded"); 221: setState(nextc); 222: return true; 223: } 224: return false; 225: } 226: } 227: 228: /** 229: * Creates an instance of {@code ReentrantLock}. 230: * This is equivalent to using {@code ReentrantLock(false)}. 231: */ 232: public ReentrantLock() { 233: sync = new NonfairSync(); 234: } 235: 236: /** 237: * Creates an instance of {@code ReentrantLock} with the 238: * given fairness policy. 239: * 240: * @param fair {@code true} if this lock should use a fair ordering policy 241: */ 242: public ReentrantLock(boolean fair) { 243: sync = (fair)? new FairSync() : new NonfairSync(); 244: } 245: 246: /** 247: * Acquires the lock. 248: * 249: * <p>Acquires the lock if it is not held by another thread and returns 250: * immediately, setting the lock hold count to one. 251: * 252: * <p>If the current thread already holds the lock then the hold 253: * count is incremented by one and the method returns immediately. 254: * 255: * <p>If the lock is held by another thread then the 256: * current thread becomes disabled for thread scheduling 257: * purposes and lies dormant until the lock has been acquired, 258: * at which time the lock hold count is set to one. 259: */ 260: public void lock() { 261: sync.lock(); 262: } 263: 264: /** 265: * Acquires the lock unless the current thread is 266: * {@linkplain Thread#interrupt interrupted}. 267: * 268: * <p>Acquires the lock if it is not held by another thread and returns 269: * immediately, setting the lock hold count to one. 270: * 271: * <p>If the current thread already holds this lock then the hold count 272: * is incremented by one and the method returns immediately. 273: * 274: * <p>If the lock is held by another thread then the 275: * current thread becomes disabled for thread scheduling 276: * purposes and lies dormant until one of two things happens: 277: * 278: * <ul> 279: * 280: * <li>The lock is acquired by the current thread; or 281: * 282: * <li>Some other thread {@linkplain Thread#interrupt interrupts} the 283: * current thread. 284: * 285: * </ul> 286: * 287: * <p>If the lock is acquired by the current thread then the lock hold 288: * count is set to one. 289: * 290: * <p>If the current thread: 291: * 292: * <ul> 293: * 294: * <li>has its interrupted status set on entry to this method; or 295: * 296: * <li>is {@linkplain Thread#interrupt interrupted} while acquiring 297: * the lock, 298: * 299: * </ul> 300: * 301: * then {@link InterruptedException} is thrown and the current thread's 302: * interrupted status is cleared. 303: * 304: * <p>In this implementation, as this method is an explicit 305: * interruption point, preference is given to responding to the 306: * interrupt over normal or reentrant acquisition of the lock. 307: * 308: * @throws InterruptedException if the current thread is interrupted 309: */ 310: public void lockInterruptibly() throws InterruptedException { 311: sync.acquireInterruptibly(1); 312: } 313: 314: /** 315: * Acquires the lock only if it is not held by another thread at the time 316: * of invocation. 317: * 318: * <p>Acquires the lock if it is not held by another thread and 319: * returns immediately with the value {@code true}, setting the 320: * lock hold count to one. Even when this lock has been set to use a 321: * fair ordering policy, a call to {@code tryLock()} <em>will</em> 322: * immediately acquire the lock if it is available, whether or not 323: * other threads are currently waiting for the lock. 324: * This "barging" behavior can be useful in certain 325: * circumstances, even though it breaks fairness. If you want to honor 326: * the fairness setting for this lock, then use 327: * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } 328: * which is almost equivalent (it also detects interruption). 329: * 330: * <p> If the current thread already holds this lock then the hold 331: * count is incremented by one and the method returns {@code true}. 332: * 333: * <p>If the lock is held by another thread then this method will return 334: * immediately with the value {@code false}. 335: * 336: * @return {@code true} if the lock was free and was acquired by the 337: * current thread, or the lock was already held by the current 338: * thread; and {@code false} otherwise 339: */ 340: public boolean tryLock() { 341: return sync.nonfairTryAcquire(1); 342: } 343: 344: /** 345: * Acquires the lock if it is not held by another thread within the given 346: * waiting time and the current thread has not been 347: * {@linkplain Thread#interrupt interrupted}. 348: * 349: * <p>Acquires the lock if it is not held by another thread and returns 350: * immediately with the value {@code true}, setting the lock hold count 351: * to one. If this lock has been set to use a fair ordering policy then 352: * an available lock <em>will not</em> be acquired if any other threads 353: * are waiting for the lock. This is in contrast to the {@link #tryLock()} 354: * method. If you want a timed {@code tryLock} that does permit barging on 355: * a fair lock then combine the timed and un-timed forms together: 356: * 357: * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... } 358: * </pre> 359: * 360: * <p>If the current thread 361: * already holds this lock then the hold count is incremented by one and 362: * the method returns {@code true}. 363: * 364: * <p>If the lock is held by another thread then the 365: * current thread becomes disabled for thread scheduling 366: * purposes and lies dormant until one of three things happens: 367: * 368: * <ul> 369: * 370: * <li>The lock is acquired by the current thread; or 371: * 372: * <li>Some other thread {@linkplain Thread#interrupt interrupts} 373: * the current thread; or 374: * 375: * <li>The specified waiting time elapses 376: * 377: * </ul> 378: * 379: * <p>If the lock is acquired then the value {@code true} is returned and 380: * the lock hold count is set to one. 381: * 382: * <p>If the current thread: 383: * 384: * <ul> 385: * 386: * <li>has its interrupted status set on entry to this method; or 387: * 388: * <li>is {@linkplain Thread#interrupt interrupted} while 389: * acquiring the lock, 390: * 391: * </ul> 392: * then {@link InterruptedException} is thrown and the current thread's 393: * interrupted status is cleared. 394: * 395: * <p>If the specified waiting time elapses then the value {@code false} 396: * is returned. If the time is less than or equal to zero, the method 397: * will not wait at all. 398: * 399: * <p>In this implementation, as this method is an explicit 400: * interruption point, preference is given to responding to the 401: * interrupt over normal or reentrant acquisition of the lock, and 402: * over reporting the elapse of the waiting time. 403: * 404: * @param timeout the time to wait for the lock 405: * @param unit the time unit of the timeout argument 406: * @return {@code true} if the lock was free and was acquired by the 407: * current thread, or the lock was already held by the current 408: * thread; and {@code false} if the waiting time elapsed before 409: * the lock could be acquired 410: * @throws InterruptedException if the current thread is interrupted 411: * @throws NullPointerException if the time unit is null 412: * 413: */ 414: public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { 415: return sync.tryAcquireNanos(1, unit.toNanos(timeout)); 416: } 417: 418: /** 419: * Attempts to release this lock. 420: * 421: * <p>If the current thread is the holder of this lock then the hold 422: * count is decremented. If the hold count is now zero then the lock 423: * is released. If the current thread is not the holder of this 424: * lock then {@link IllegalMonitorStateException} is thrown. 425: * 426: * @throws IllegalMonitorStateException if the current thread does not 427: * hold this lock 428: */ 429: public void unlock() { 430: sync.release(1); 431: } 432: 433: /** 434: * Returns a {@link Condition} instance for use with this 435: * {@link Lock} instance. 436: * 437: * <p>The returned {@link Condition} instance supports the same 438: * usages as do the {@link Object} monitor methods ({@link 439: * Object#wait() wait}, {@link Object#notify notify}, and {@link 440: * Object#notifyAll notifyAll}) when used with the built-in 441: * monitor lock. 442: * 443: * <ul> 444: * 445: * <li>If this lock is not held when any of the {@link Condition} 446: * {@linkplain Condition#await() waiting} or {@linkplain 447: * Condition#signal signalling} methods are called, then an {@link 448: * IllegalMonitorStateException} is thrown. 449: * 450: * <li>When the condition {@linkplain Condition#await() waiting} 451: * methods are called the lock is released and, before they 452: * return, the lock is reacquired and the lock hold count restored 453: * to what it was when the method was called. 454: * 455: * <li>If a thread is {@linkplain Thread#interrupt interrupted} 456: * while waiting then the wait will terminate, an {@link 457: * InterruptedException} will be thrown, and the thread's 458: * interrupted status will be cleared. 459: * 460: * <li> Waiting threads are signalled in FIFO order. 461: * 462: * <li>The ordering of lock reacquisition for threads returning 463: * from waiting methods is the same as for threads initially 464: * acquiring the lock, which is in the default case not specified, 465: * but for <em>fair</em> locks favors those threads that have been 466: * waiting the longest. 467: * 468: * </ul> 469: * 470: * @return the Condition object 471: */ 472: public Condition newCondition() { 473: return sync.newCondition(); 474: } 475: 476: /** 477: * Queries the number of holds on this lock by the current thread. 478: * 479: * <p>A thread has a hold on a lock for each lock action that is not 480: * matched by an unlock action. 481: * 482: * <p>The hold count information is typically only used for testing and 483: * debugging purposes. For example, if a certain section of code should 484: * not be entered with the lock already held then we can assert that 485: * fact: 486: * 487: * <pre> 488: * class X { 489: * ReentrantLock lock = new ReentrantLock(); 490: * // ... 491: * public void m() { 492: * assert lock.getHoldCount() == 0; 493: * lock.lock(); 494: * try { 495: * // ... method body 496: * } finally { 497: * lock.unlock(); 498: * } 499: * } 500: * } 501: * </pre> 502: * 503: * @return the number of holds on this lock by the current thread, 504: * or zero if this lock is not held by the current thread 505: */ 506: public int getHoldCount() { 507: return sync.getHoldCount(); 508: } 509: 510: /** 511: * Queries if this lock is held by the current thread. 512: * 513: * <p>Analogous to the {@link Thread#holdsLock} method for built-in 514: * monitor locks, this method is typically used for debugging and 515: * testing. For example, a method that should only be called while 516: * a lock is held can assert that this is the case: 517: * 518: * <pre> 519: * class X { 520: * ReentrantLock lock = new ReentrantLock(); 521: * // ... 522: * 523: * public void m() { 524: * assert lock.isHeldByCurrentThread(); 525: * // ... method body 526: * } 527: * } 528: * </pre> 529: * 530: * <p>It can also be used to ensure that a reentrant lock is used 531: * in a non-reentrant manner, for example: 532: * 533: * <pre> 534: * class X { 535: * ReentrantLock lock = new ReentrantLock(); 536: * // ... 537: * 538: * public void m() { 539: * assert !lock.isHeldByCurrentThread(); 540: * lock.lock(); 541: * try { 542: * // ... method body 543: * } finally { 544: * lock.unlock(); 545: * } 546: * } 547: * } 548: * </pre> 549: * 550: * @return {@code true} if current thread holds this lock and 551: * {@code false} otherwise 552: */ 553: public boolean isHeldByCurrentThread() { 554: return sync.isHeldExclusively(); 555: } 556: 557: /** 558: * Queries if this lock is held by any thread. This method is 559: * designed for use in monitoring of the system state, 560: * not for synchronization control. 561: * 562: * @return {@code true} if any thread holds this lock and 563: * {@code false} otherwise 564: */ 565: public boolean isLocked() { 566: return sync.isLocked(); 567: } 568: 569: /** 570: * Returns {@code true} if this lock has fairness set true. 571: * 572: * @return {@code true} if this lock has fairness set true 573: */ 574: public final boolean isFair() { 575: return sync instanceof FairSync; 576: } 577: 578: /** 579: * Returns the thread that currently owns this lock, or 580: * {@code null} if not owned. When this method is called by a 581: * thread that is not the owner, the return value reflects a 582: * best-effort approximation of current lock status. For example, 583: * the owner may be momentarily {@code null} even if there are 584: * threads trying to acquire the lock but have not yet done so. 585: * This method is designed to facilitate construction of 586: * subclasses that provide more extensive lock monitoring 587: * facilities. 588: * 589: * @return the owner, or {@code null} if not owned 590: */ 591: protected Thread getOwner() { 592: return sync.getOwner(); 593: } 594: 595: /** 596: * Queries whether any threads are waiting to acquire this lock. Note that 597: * because cancellations may occur at any time, a {@code true} 598: * return does not guarantee that any other thread will ever 599: * acquire this lock. This method is designed primarily for use in 600: * monitoring of the system state. 601: * 602: * @return {@code true} if there may be other threads waiting to 603: * acquire the lock 604: */ 605: public final boolean hasQueuedThreads() { 606: return sync.hasQueuedThreads(); 607: } 608: 609: 610: /** 611: * Queries whether the given thread is waiting to acquire this 612: * lock. Note that because cancellations may occur at any time, a 613: * {@code true} return does not guarantee that this thread 614: * will ever acquire this lock. This method is designed primarily for use 615: * in monitoring of the system state. 616: * 617: * @param thread the thread 618: * @return {@code true} if the given thread is queued waiting for this lock 619: * @throws NullPointerException if the thread is null 620: */ 621: public final boolean hasQueuedThread(Thread thread) { 622: return sync.isQueued(thread); 623: } 624: 625: 626: /** 627: * Returns an estimate of the number of threads waiting to 628: * acquire this lock. The value is only an estimate because the number of 629: * threads may change dynamically while this method traverses 630: * internal data structures. This method is designed for use in 631: * monitoring of the system state, not for synchronization 632: * control. 633: * 634: * @return the estimated number of threads waiting for this lock 635: */ 636: public final int getQueueLength() { 637: return sync.getQueueLength(); 638: } 639: 640: /** 641: * Returns a collection containing threads that may be waiting to 642: * acquire this lock. Because the actual set of threads may change 643: * dynamically while constructing this result, the returned 644: * collection is only a best-effort estimate. The elements of the 645: * returned collection are in no particular order. This method is 646: * designed to facilitate construction of subclasses that provide 647: * more extensive monitoring facilities. 648: * 649: * @return the collection of threads 650: */ 651: protected Collection<Thread> getQueuedThreads() { 652: return sync.getQueuedThreads(); 653: } 654: 655: /** 656: * Queries whether any threads are waiting on the given condition 657: * associated with this lock. Note that because timeouts and 658: * interrupts may occur at any time, a {@code true} return does 659: * not guarantee that a future {@code signal} will awaken any 660: * threads. This method is designed primarily for use in 661: * monitoring of the system state. 662: * 663: * @param condition the condition 664: * @return {@code true} if there are any waiting threads 665: * @throws IllegalMonitorStateException if this lock is not held 666: * @throws IllegalArgumentException if the given condition is 667: * not associated with this lock 668: * @throws NullPointerException if the condition is null 669: */ 670: public boolean hasWaiters(Condition condition) { 671: if (condition == null) 672: throw new NullPointerException(); 673: if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) 674: throw new IllegalArgumentException("not owner"); 675: return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition); 676: } 677: 678: /** 679: * Returns an estimate of the number of threads waiting on the 680: * given condition associated with this lock. Note that because 681: * timeouts and interrupts may occur at any time, the estimate 682: * serves only as an upper bound on the actual number of waiters. 683: * This method is designed for use in monitoring of the system 684: * state, not for synchronization control. 685: * 686: * @param condition the condition 687: * @return the estimated number of waiting threads 688: * @throws IllegalMonitorStateException if this lock is not held 689: * @throws IllegalArgumentException if the given condition is 690: * not associated with this lock 691: * @throws NullPointerException if the condition is null 692: */ 693: public int getWaitQueueLength(Condition condition) { 694: if (condition == null) 695: throw new NullPointerException(); 696: if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) 697: throw new IllegalArgumentException("not owner"); 698: return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition); 699: } 700: 701: /** 702: * Returns a collection containing those threads that may be 703: * waiting on the given condition associated with this lock. 704: * Because the actual set of threads may change dynamically while 705: * constructing this result, the returned collection is only a 706: * best-effort estimate. The elements of the returned collection 707: * are in no particular order. This method is designed to 708: * facilitate construction of subclasses that provide more 709: * extensive condition monitoring facilities. 710: * 711: * @param condition the condition 712: * @return the collection of threads 713: * @throws IllegalMonitorStateException if this lock is not held 714: * @throws IllegalArgumentException if the given condition is 715: * not associated with this lock 716: * @throws NullPointerException if the condition is null 717: */ 718: protected Collection<Thread> getWaitingThreads(Condition condition) { 719: if (condition == null) 720: throw new NullPointerException(); 721: if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) 722: throw new IllegalArgumentException("not owner"); 723: return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition); 724: } 725: 726: /** 727: * Returns a string identifying this lock, as well as its lock state. 728: * The state, in brackets, includes either the String {@code "Unlocked"} 729: * or the String {@code "Locked by"} followed by the 730: * {@linkplain Thread#getName name} of the owning thread. 731: * 732: * @return a string identifying this lock, as well as its lock state 733: */ 734: public String toString() { 735: Thread o = sync.getOwner(); 736: return super.toString() + ((o == null) ? 737: "[Unlocked]" : 738: "[Locked by thread " + o.getName() + "]"); 739: } 740: }
GNU Classpath (0.98) |