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/publicdomain/zero/1.0/ 5 */ 6 7 package java.util.concurrent.locks; 8 9 import java.util.Collection; 10 import java.util.concurrent.TimeUnit; 11 12 /** 13 * An implementation of {@link ReadWriteLock} supporting similar 14 * semantics to {@link ReentrantLock}. 15 * <p>This class has the following properties: 16 * 17 * <ul> 18 * <li><b>Acquisition order</b> 19 * 20 * <p>This class does not impose a reader or writer preference 21 * ordering for lock access. However, it does support an optional 22 * <em>fairness</em> policy. 23 * 24 * <dl> 25 * <dt><b><i>Non-fair mode (default)</i></b> 26 * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif"> 27 * When constructed as non-fair (the default), the order of entry 28 * to the read and write lock is unspecified, subject to reentrancy 29 * constraints. A nonfair lock that is continuously contended may 30 * indefinitely postpone one or more reader or writer threads, but 31 * will normally have higher throughput than a fair lock. 32 * 33 * <dt><b><i>Fair mode</i></b> 34 * <dd style="font-family:'DejaVu Sans', Arial, Helvetica, sans-serif"> 35 * When constructed as fair, threads contend for entry using an 36 * approximately arrival-order policy. When the currently held lock 37 * is released, either the longest-waiting single writer thread will 38 * be assigned the write lock, or if there is a group of reader threads 39 * waiting longer than all waiting writer threads, that group will be 40 * assigned the read lock. 41 * 42 * <p>A thread that tries to acquire a fair read lock (non-reentrantly) 43 * will block if either the write lock is held, or there is a waiting 44 * writer thread. The thread will not acquire the read lock until 45 * after the oldest currently waiting writer thread has acquired and 46 * released the write lock. Of course, if a waiting writer abandons 47 * its wait, leaving one or more reader threads as the longest waiters 48 * in the queue with the write lock free, then those readers will be 49 * assigned the read lock. 50 * 51 * <p>A thread that tries to acquire a fair write lock (non-reentrantly) 52 * will block unless both the read lock and write lock are free (which 53 * implies there are no waiting threads). (Note that the non-blocking 54 * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods 55 * do not honor this fair setting and will immediately acquire the lock 56 * if it is possible, regardless of waiting threads.) 57 * </dl> 58 * 59 * <li><b>Reentrancy</b> 60 * 61 * <p>This lock allows both readers and writers to reacquire read or 62 * write locks in the style of a {@link ReentrantLock}. Non-reentrant 63 * readers are not allowed until all write locks held by the writing 64 * thread have been released. 65 * 66 * <p>Additionally, a writer can acquire the read lock, but not 67 * vice-versa. Among other applications, reentrancy can be useful 68 * when write locks are held during calls or callbacks to methods that 69 * perform reads under read locks. If a reader tries to acquire the 70 * write lock it will never succeed. 71 * 72 * <li><b>Lock downgrading</b> 73 * <p>Reentrancy also allows downgrading from the write lock to a read lock, 74 * by acquiring the write lock, then the read lock and then releasing the 75 * write lock. However, upgrading from a read lock to the write lock is 76 * <b>not</b> possible. 77 * 78 * <li><b>Interruption of lock acquisition</b> 79 * <p>The read lock and write lock both support interruption during lock 80 * acquisition. 81 * 82 * <li><b>{@link Condition} support</b> 83 * <p>The write lock provides a {@link Condition} implementation that 84 * behaves in the same way, with respect to the write lock, as the 85 * {@link Condition} implementation provided by 86 * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}. 87 * This {@link Condition} can, of course, only be used with the write lock. 88 * 89 * <p>The read lock does not support a {@link Condition} and 90 * {@code readLock().newCondition()} throws 91 * {@code UnsupportedOperationException}. 92 * 93 * <li><b>Instrumentation</b> 94 * <p>This class supports methods to determine whether locks 95 * are held or contended. These methods are designed for monitoring 96 * system state, not for synchronization control. 97 * </ul> 98 * 99 * <p>Serialization of this class behaves in the same way as built-in 100 * locks: a deserialized lock is in the unlocked state, regardless of 101 * its state when serialized. 102 * 103 * <p><b>Sample usages</b>. Here is a code sketch showing how to perform 104 * lock downgrading after updating a cache (exception handling is 105 * particularly tricky when handling multiple locks in a non-nested 106 * fashion): 107 * 108 * <pre> {@code 109 * class CachedData { 110 * Object data; 111 * volatile boolean cacheValid; 112 * final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 113 * 114 * void processCachedData() { 115 * rwl.readLock().lock(); 116 * if (!cacheValid) { 117 * // Must release read lock before acquiring write lock 118 * rwl.readLock().unlock(); 119 * rwl.writeLock().lock(); 120 * try { 121 * // Recheck state because another thread might have 122 * // acquired write lock and changed state before we did. 123 * if (!cacheValid) { 124 * data = ... 125 * cacheValid = true; 126 * } 127 * // Downgrade by acquiring read lock before releasing write lock 128 * rwl.readLock().lock(); 129 * } finally { 130 * rwl.writeLock().unlock(); // Unlock write, still hold read 131 * } 132 * } 133 * 134 * try { 135 * use(data); 136 * } finally { 137 * rwl.readLock().unlock(); 138 * } 139 * } 140 * }}</pre> 141 * 142 * ReentrantReadWriteLocks can be used to improve concurrency in some 143 * uses of some kinds of Collections. This is typically worthwhile 144 * only when the collections are expected to be large, accessed by 145 * more reader threads than writer threads, and entail operations with 146 * overhead that outweighs synchronization overhead. For example, here 147 * is a class using a TreeMap that is expected to be large and 148 * concurrently accessed. 149 * 150 * <pre> {@code 151 * class RWDictionary { 152 * private final Map<String, Data> m = new TreeMap<>(); 153 * private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 154 * private final Lock r = rwl.readLock(); 155 * private final Lock w = rwl.writeLock(); 156 * 157 * public Data get(String key) { 158 * r.lock(); 159 * try { return m.get(key); } 160 * finally { r.unlock(); } 161 * } 162 * public List<String> allKeys() { 163 * r.lock(); 164 * try { return new ArrayList<>(m.keySet()); } 165 * finally { r.unlock(); } 166 * } 167 * public Data put(String key, Data value) { 168 * w.lock(); 169 * try { return m.put(key, value); } 170 * finally { w.unlock(); } 171 * } 172 * public void clear() { 173 * w.lock(); 174 * try { m.clear(); } 175 * finally { w.unlock(); } 176 * } 177 * }}</pre> 178 * 179 * <h3>Implementation Notes</h3> 180 * 181 * <p>This lock supports a maximum of 65535 recursive write locks 182 * and 65535 read locks. Attempts to exceed these limits result in 183 * {@link Error} throws from locking methods. 184 * 185 * @since 1.5 186 * @author Doug Lea 187 */ 188 public class ReentrantReadWriteLock 189 implements ReadWriteLock, java.io.Serializable { 190 private static final long serialVersionUID = -6992448646407690164L; 191 /** Inner class providing readlock */ 192 private final ReentrantReadWriteLock.ReadLock readerLock; 193 /** Inner class providing writelock */ 194 private final ReentrantReadWriteLock.WriteLock writerLock; 195 /** Performs all synchronization mechanics */ 196 final Sync sync; 197 198 /** 199 * Creates a new {@code ReentrantReadWriteLock} with 200 * default (nonfair) ordering properties. 201 */ ReentrantReadWriteLock()202 public ReentrantReadWriteLock() { 203 this(false); 204 } 205 206 /** 207 * Creates a new {@code ReentrantReadWriteLock} with 208 * the given fairness policy. 209 * 210 * @param fair {@code true} if this lock should use a fair ordering policy 211 */ ReentrantReadWriteLock(boolean fair)212 public ReentrantReadWriteLock(boolean fair) { 213 sync = fair ? new FairSync() : new NonfairSync(); 214 readerLock = new ReadLock(this); 215 writerLock = new WriteLock(this); 216 } 217 writeLock()218 public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; } readLock()219 public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; } 220 221 /** 222 * Synchronization implementation for ReentrantReadWriteLock. 223 * Subclassed into fair and nonfair versions. 224 */ 225 abstract static class Sync extends AbstractQueuedSynchronizer { 226 private static final long serialVersionUID = 6317671515068378041L; 227 228 /* 229 * Read vs write count extraction constants and functions. 230 * Lock state is logically divided into two unsigned shorts: 231 * The lower one representing the exclusive (writer) lock hold count, 232 * and the upper the shared (reader) hold count. 233 */ 234 235 static final int SHARED_SHIFT = 16; 236 static final int SHARED_UNIT = (1 << SHARED_SHIFT); 237 static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; 238 static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; 239 240 /** Returns the number of shared holds represented in count. */ sharedCount(int c)241 static int sharedCount(int c) { return c >>> SHARED_SHIFT; } 242 /** Returns the number of exclusive holds represented in count. */ exclusiveCount(int c)243 static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; } 244 245 /** 246 * A counter for per-thread read hold counts. 247 * Maintained as a ThreadLocal; cached in cachedHoldCounter. 248 */ 249 static final class HoldCounter { 250 int count; // initially 0 251 // Use id, not reference, to avoid garbage retention 252 final long tid = getThreadId(Thread.currentThread()); 253 } 254 255 /** 256 * ThreadLocal subclass. Easiest to explicitly define for sake 257 * of deserialization mechanics. 258 */ 259 static final class ThreadLocalHoldCounter 260 extends ThreadLocal<HoldCounter> { initialValue()261 public HoldCounter initialValue() { 262 return new HoldCounter(); 263 } 264 } 265 266 /** 267 * The number of reentrant read locks held by current thread. 268 * Initialized only in constructor and readObject. 269 * Removed whenever a thread's read hold count drops to 0. 270 */ 271 private transient ThreadLocalHoldCounter readHolds; 272 273 /** 274 * The hold count of the last thread to successfully acquire 275 * readLock. This saves ThreadLocal lookup in the common case 276 * where the next thread to release is the last one to 277 * acquire. This is non-volatile since it is just used 278 * as a heuristic, and would be great for threads to cache. 279 * 280 * <p>Can outlive the Thread for which it is caching the read 281 * hold count, but avoids garbage retention by not retaining a 282 * reference to the Thread. 283 * 284 * <p>Accessed via a benign data race; relies on the memory 285 * model's final field and out-of-thin-air guarantees. 286 */ 287 private transient HoldCounter cachedHoldCounter; 288 289 /** 290 * firstReader is the first thread to have acquired the read lock. 291 * firstReaderHoldCount is firstReader's hold count. 292 * 293 * <p>More precisely, firstReader is the unique thread that last 294 * changed the shared count from 0 to 1, and has not released the 295 * read lock since then; null if there is no such thread. 296 * 297 * <p>Cannot cause garbage retention unless the thread terminated 298 * without relinquishing its read locks, since tryReleaseShared 299 * sets it to null. 300 * 301 * <p>Accessed via a benign data race; relies on the memory 302 * model's out-of-thin-air guarantees for references. 303 * 304 * <p>This allows tracking of read holds for uncontended read 305 * locks to be very cheap. 306 */ 307 private transient Thread firstReader; 308 private transient int firstReaderHoldCount; 309 Sync()310 Sync() { 311 readHolds = new ThreadLocalHoldCounter(); 312 setState(getState()); // ensures visibility of readHolds 313 } 314 315 /* 316 * Acquires and releases use the same code for fair and 317 * nonfair locks, but differ in whether/how they allow barging 318 * when queues are non-empty. 319 */ 320 321 /** 322 * Returns true if the current thread, when trying to acquire 323 * the read lock, and otherwise eligible to do so, should block 324 * because of policy for overtaking other waiting threads. 325 */ readerShouldBlock()326 abstract boolean readerShouldBlock(); 327 328 /** 329 * Returns true if the current thread, when trying to acquire 330 * the write lock, and otherwise eligible to do so, should block 331 * because of policy for overtaking other waiting threads. 332 */ writerShouldBlock()333 abstract boolean writerShouldBlock(); 334 335 /* 336 * Note that tryRelease and tryAcquire can be called by 337 * Conditions. So it is possible that their arguments contain 338 * both read and write holds that are all released during a 339 * condition wait and re-established in tryAcquire. 340 */ 341 tryRelease(int releases)342 protected final boolean tryRelease(int releases) { 343 if (!isHeldExclusively()) 344 throw new IllegalMonitorStateException(); 345 int nextc = getState() - releases; 346 boolean free = exclusiveCount(nextc) == 0; 347 if (free) 348 setExclusiveOwnerThread(null); 349 setState(nextc); 350 return free; 351 } 352 tryAcquire(int acquires)353 protected final boolean tryAcquire(int acquires) { 354 /* 355 * Walkthrough: 356 * 1. If read count nonzero or write count nonzero 357 * and owner is a different thread, fail. 358 * 2. If count would saturate, fail. (This can only 359 * happen if count is already nonzero.) 360 * 3. Otherwise, this thread is eligible for lock if 361 * it is either a reentrant acquire or 362 * queue policy allows it. If so, update state 363 * and set owner. 364 */ 365 Thread current = Thread.currentThread(); 366 int c = getState(); 367 int w = exclusiveCount(c); 368 if (c != 0) { 369 // (Note: if c != 0 and w == 0 then shared count != 0) 370 if (w == 0 || current != getExclusiveOwnerThread()) 371 return false; 372 if (w + exclusiveCount(acquires) > MAX_COUNT) 373 throw new Error("Maximum lock count exceeded"); 374 // Reentrant acquire 375 setState(c + acquires); 376 return true; 377 } 378 if (writerShouldBlock() || 379 !compareAndSetState(c, c + acquires)) 380 return false; 381 setExclusiveOwnerThread(current); 382 return true; 383 } 384 tryReleaseShared(int unused)385 protected final boolean tryReleaseShared(int unused) { 386 Thread current = Thread.currentThread(); 387 if (firstReader == current) { 388 // assert firstReaderHoldCount > 0; 389 if (firstReaderHoldCount == 1) 390 firstReader = null; 391 else 392 firstReaderHoldCount--; 393 } else { 394 HoldCounter rh = cachedHoldCounter; 395 if (rh == null || rh.tid != getThreadId(current)) 396 rh = readHolds.get(); 397 int count = rh.count; 398 if (count <= 1) { 399 readHolds.remove(); 400 if (count <= 0) 401 throw unmatchedUnlockException(); 402 } 403 --rh.count; 404 } 405 for (;;) { 406 int c = getState(); 407 int nextc = c - SHARED_UNIT; 408 if (compareAndSetState(c, nextc)) 409 // Releasing the read lock has no effect on readers, 410 // but it may allow waiting writers to proceed if 411 // both read and write locks are now free. 412 return nextc == 0; 413 } 414 } 415 unmatchedUnlockException()416 private IllegalMonitorStateException unmatchedUnlockException() { 417 return new IllegalMonitorStateException( 418 "attempt to unlock read lock, not locked by current thread"); 419 } 420 tryAcquireShared(int unused)421 protected final int tryAcquireShared(int unused) { 422 /* 423 * Walkthrough: 424 * 1. If write lock held by another thread, fail. 425 * 2. Otherwise, this thread is eligible for 426 * lock wrt state, so ask if it should block 427 * because of queue policy. If not, try 428 * to grant by CASing state and updating count. 429 * Note that step does not check for reentrant 430 * acquires, which is postponed to full version 431 * to avoid having to check hold count in 432 * the more typical non-reentrant case. 433 * 3. If step 2 fails either because thread 434 * apparently not eligible or CAS fails or count 435 * saturated, chain to version with full retry loop. 436 */ 437 Thread current = Thread.currentThread(); 438 int c = getState(); 439 if (exclusiveCount(c) != 0 && 440 getExclusiveOwnerThread() != current) 441 return -1; 442 int r = sharedCount(c); 443 if (!readerShouldBlock() && 444 r < MAX_COUNT && 445 compareAndSetState(c, c + SHARED_UNIT)) { 446 if (r == 0) { 447 firstReader = current; 448 firstReaderHoldCount = 1; 449 } else if (firstReader == current) { 450 firstReaderHoldCount++; 451 } else { 452 HoldCounter rh = cachedHoldCounter; 453 if (rh == null || rh.tid != getThreadId(current)) 454 cachedHoldCounter = rh = readHolds.get(); 455 else if (rh.count == 0) 456 readHolds.set(rh); 457 rh.count++; 458 } 459 return 1; 460 } 461 return fullTryAcquireShared(current); 462 } 463 464 /** 465 * Full version of acquire for reads, that handles CAS misses 466 * and reentrant reads not dealt with in tryAcquireShared. 467 */ fullTryAcquireShared(Thread current)468 final int fullTryAcquireShared(Thread current) { 469 /* 470 * This code is in part redundant with that in 471 * tryAcquireShared but is simpler overall by not 472 * complicating tryAcquireShared with interactions between 473 * retries and lazily reading hold counts. 474 */ 475 HoldCounter rh = null; 476 for (;;) { 477 int c = getState(); 478 if (exclusiveCount(c) != 0) { 479 if (getExclusiveOwnerThread() != current) 480 return -1; 481 // else we hold the exclusive lock; blocking here 482 // would cause deadlock. 483 } else if (readerShouldBlock()) { 484 // Make sure we're not acquiring read lock reentrantly 485 if (firstReader == current) { 486 // assert firstReaderHoldCount > 0; 487 } else { 488 if (rh == null) { 489 rh = cachedHoldCounter; 490 if (rh == null || rh.tid != getThreadId(current)) { 491 rh = readHolds.get(); 492 if (rh.count == 0) 493 readHolds.remove(); 494 } 495 } 496 if (rh.count == 0) 497 return -1; 498 } 499 } 500 if (sharedCount(c) == MAX_COUNT) 501 throw new Error("Maximum lock count exceeded"); 502 if (compareAndSetState(c, c + SHARED_UNIT)) { 503 if (sharedCount(c) == 0) { 504 firstReader = current; 505 firstReaderHoldCount = 1; 506 } else if (firstReader == current) { 507 firstReaderHoldCount++; 508 } else { 509 if (rh == null) 510 rh = cachedHoldCounter; 511 if (rh == null || rh.tid != getThreadId(current)) 512 rh = readHolds.get(); 513 else if (rh.count == 0) 514 readHolds.set(rh); 515 rh.count++; 516 cachedHoldCounter = rh; // cache for release 517 } 518 return 1; 519 } 520 } 521 } 522 523 /** 524 * Performs tryLock for write, enabling barging in both modes. 525 * This is identical in effect to tryAcquire except for lack 526 * of calls to writerShouldBlock. 527 */ tryWriteLock()528 final boolean tryWriteLock() { 529 Thread current = Thread.currentThread(); 530 int c = getState(); 531 if (c != 0) { 532 int w = exclusiveCount(c); 533 if (w == 0 || current != getExclusiveOwnerThread()) 534 return false; 535 if (w == MAX_COUNT) 536 throw new Error("Maximum lock count exceeded"); 537 } 538 if (!compareAndSetState(c, c + 1)) 539 return false; 540 setExclusiveOwnerThread(current); 541 return true; 542 } 543 544 /** 545 * Performs tryLock for read, enabling barging in both modes. 546 * This is identical in effect to tryAcquireShared except for 547 * lack of calls to readerShouldBlock. 548 */ tryReadLock()549 final boolean tryReadLock() { 550 Thread current = Thread.currentThread(); 551 for (;;) { 552 int c = getState(); 553 if (exclusiveCount(c) != 0 && 554 getExclusiveOwnerThread() != current) 555 return false; 556 int r = sharedCount(c); 557 if (r == MAX_COUNT) 558 throw new Error("Maximum lock count exceeded"); 559 if (compareAndSetState(c, c + SHARED_UNIT)) { 560 if (r == 0) { 561 firstReader = current; 562 firstReaderHoldCount = 1; 563 } else if (firstReader == current) { 564 firstReaderHoldCount++; 565 } else { 566 HoldCounter rh = cachedHoldCounter; 567 if (rh == null || rh.tid != getThreadId(current)) 568 cachedHoldCounter = rh = readHolds.get(); 569 else if (rh.count == 0) 570 readHolds.set(rh); 571 rh.count++; 572 } 573 return true; 574 } 575 } 576 } 577 isHeldExclusively()578 protected final boolean isHeldExclusively() { 579 // While we must in general read state before owner, 580 // we don't need to do so to check if current thread is owner 581 return getExclusiveOwnerThread() == Thread.currentThread(); 582 } 583 584 // Methods relayed to outer class 585 newCondition()586 final ConditionObject newCondition() { 587 return new ConditionObject(); 588 } 589 getOwner()590 final Thread getOwner() { 591 // Must read state before owner to ensure memory consistency 592 return ((exclusiveCount(getState()) == 0) ? 593 null : 594 getExclusiveOwnerThread()); 595 } 596 getReadLockCount()597 final int getReadLockCount() { 598 return sharedCount(getState()); 599 } 600 isWriteLocked()601 final boolean isWriteLocked() { 602 return exclusiveCount(getState()) != 0; 603 } 604 getWriteHoldCount()605 final int getWriteHoldCount() { 606 return isHeldExclusively() ? exclusiveCount(getState()) : 0; 607 } 608 getReadHoldCount()609 final int getReadHoldCount() { 610 if (getReadLockCount() == 0) 611 return 0; 612 613 Thread current = Thread.currentThread(); 614 if (firstReader == current) 615 return firstReaderHoldCount; 616 617 HoldCounter rh = cachedHoldCounter; 618 if (rh != null && rh.tid == getThreadId(current)) 619 return rh.count; 620 621 int count = readHolds.get().count; 622 if (count == 0) readHolds.remove(); 623 return count; 624 } 625 626 /** 627 * Reconstitutes the instance from a stream (that is, deserializes it). 628 */ readObject(java.io.ObjectInputStream s)629 private void readObject(java.io.ObjectInputStream s) 630 throws java.io.IOException, ClassNotFoundException { 631 s.defaultReadObject(); 632 readHolds = new ThreadLocalHoldCounter(); 633 setState(0); // reset to unlocked state 634 } 635 getCount()636 final int getCount() { return getState(); } 637 } 638 639 /** 640 * Nonfair version of Sync 641 */ 642 static final class NonfairSync extends Sync { 643 private static final long serialVersionUID = -8159625535654395037L; writerShouldBlock()644 final boolean writerShouldBlock() { 645 return false; // writers can always barge 646 } readerShouldBlock()647 final boolean readerShouldBlock() { 648 /* As a heuristic to avoid indefinite writer starvation, 649 * block if the thread that momentarily appears to be head 650 * of queue, if one exists, is a waiting writer. This is 651 * only a probabilistic effect since a new reader will not 652 * block if there is a waiting writer behind other enabled 653 * readers that have not yet drained from the queue. 654 */ 655 return apparentlyFirstQueuedIsExclusive(); 656 } 657 } 658 659 /** 660 * Fair version of Sync 661 */ 662 static final class FairSync extends Sync { 663 private static final long serialVersionUID = -2274990926593161451L; writerShouldBlock()664 final boolean writerShouldBlock() { 665 return hasQueuedPredecessors(); 666 } readerShouldBlock()667 final boolean readerShouldBlock() { 668 return hasQueuedPredecessors(); 669 } 670 } 671 672 /** 673 * The lock returned by method {@link ReentrantReadWriteLock#readLock}. 674 */ 675 public static class ReadLock implements Lock, java.io.Serializable { 676 private static final long serialVersionUID = -5992448646407690164L; 677 private final Sync sync; 678 679 /** 680 * Constructor for use by subclasses. 681 * 682 * @param lock the outer lock object 683 * @throws NullPointerException if the lock is null 684 */ ReadLock(ReentrantReadWriteLock lock)685 protected ReadLock(ReentrantReadWriteLock lock) { 686 sync = lock.sync; 687 } 688 689 /** 690 * Acquires the read lock. 691 * 692 * <p>Acquires the read lock if the write lock is not held by 693 * another thread and returns immediately. 694 * 695 * <p>If the write lock is held by another thread then 696 * the current thread becomes disabled for thread scheduling 697 * purposes and lies dormant until the read lock has been acquired. 698 */ lock()699 public void lock() { 700 sync.acquireShared(1); 701 } 702 703 /** 704 * Acquires the read lock unless the current thread is 705 * {@linkplain Thread#interrupt interrupted}. 706 * 707 * <p>Acquires the read lock if the write lock is not held 708 * by another thread and returns immediately. 709 * 710 * <p>If the write lock is held by another thread then the 711 * current thread becomes disabled for thread scheduling 712 * purposes and lies dormant until one of two things happens: 713 * 714 * <ul> 715 * 716 * <li>The read lock is acquired by the current thread; or 717 * 718 * <li>Some other thread {@linkplain Thread#interrupt interrupts} 719 * the current thread. 720 * 721 * </ul> 722 * 723 * <p>If the current thread: 724 * 725 * <ul> 726 * 727 * <li>has its interrupted status set on entry to this method; or 728 * 729 * <li>is {@linkplain Thread#interrupt interrupted} while 730 * acquiring the read lock, 731 * 732 * </ul> 733 * 734 * then {@link InterruptedException} is thrown and the current 735 * thread's interrupted status is cleared. 736 * 737 * <p>In this implementation, as this method is an explicit 738 * interruption point, preference is given to responding to 739 * the interrupt over normal or reentrant acquisition of the 740 * lock. 741 * 742 * @throws InterruptedException if the current thread is interrupted 743 */ lockInterruptibly()744 public void lockInterruptibly() throws InterruptedException { 745 sync.acquireSharedInterruptibly(1); 746 } 747 748 /** 749 * Acquires the read lock only if the write lock is not held by 750 * another thread at the time of invocation. 751 * 752 * <p>Acquires the read lock if the write lock is not held by 753 * another thread and returns immediately with the value 754 * {@code true}. Even when this lock has been set to use a 755 * fair ordering policy, a call to {@code tryLock()} 756 * <em>will</em> immediately acquire the read lock if it is 757 * available, whether or not other threads are currently 758 * waiting for the read lock. This "barging" behavior 759 * can be useful in certain circumstances, even though it 760 * breaks fairness. If you want to honor the fairness setting 761 * for this lock, then use {@link #tryLock(long, TimeUnit) 762 * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent 763 * (it also detects interruption). 764 * 765 * <p>If the write lock is held by another thread then 766 * this method will return immediately with the value 767 * {@code false}. 768 * 769 * @return {@code true} if the read lock was acquired 770 */ tryLock()771 public boolean tryLock() { 772 return sync.tryReadLock(); 773 } 774 775 /** 776 * Acquires the read lock if the write lock is not held by 777 * another thread within the given waiting time and the 778 * current thread has not been {@linkplain Thread#interrupt 779 * interrupted}. 780 * 781 * <p>Acquires the read lock if the write lock is not held by 782 * another thread and returns immediately with the value 783 * {@code true}. If this lock has been set to use a fair 784 * ordering policy then an available lock <em>will not</em> be 785 * acquired if any other threads are waiting for the 786 * lock. This is in contrast to the {@link #tryLock()} 787 * method. If you want a timed {@code tryLock} that does 788 * permit barging on a fair lock then combine the timed and 789 * un-timed forms together: 790 * 791 * <pre> {@code 792 * if (lock.tryLock() || 793 * lock.tryLock(timeout, unit)) { 794 * ... 795 * }}</pre> 796 * 797 * <p>If the write lock is held by another thread then the 798 * current thread becomes disabled for thread scheduling 799 * purposes and lies dormant until one of three things happens: 800 * 801 * <ul> 802 * 803 * <li>The read lock is acquired by the current thread; or 804 * 805 * <li>Some other thread {@linkplain Thread#interrupt interrupts} 806 * the current thread; or 807 * 808 * <li>The specified waiting time elapses. 809 * 810 * </ul> 811 * 812 * <p>If the read lock is acquired then the value {@code true} is 813 * returned. 814 * 815 * <p>If the current thread: 816 * 817 * <ul> 818 * 819 * <li>has its interrupted status set on entry to this method; or 820 * 821 * <li>is {@linkplain Thread#interrupt interrupted} while 822 * acquiring the read lock, 823 * 824 * </ul> then {@link InterruptedException} is thrown and the 825 * current thread's interrupted status is cleared. 826 * 827 * <p>If the specified waiting time elapses then the value 828 * {@code false} is returned. If the time is less than or 829 * equal to zero, the method will not wait at all. 830 * 831 * <p>In this implementation, as this method is an explicit 832 * interruption point, preference is given to responding to 833 * the interrupt over normal or reentrant acquisition of the 834 * lock, and over reporting the elapse of the waiting time. 835 * 836 * @param timeout the time to wait for the read lock 837 * @param unit the time unit of the timeout argument 838 * @return {@code true} if the read lock was acquired 839 * @throws InterruptedException if the current thread is interrupted 840 * @throws NullPointerException if the time unit is null 841 */ tryLock(long timeout, TimeUnit unit)842 public boolean tryLock(long timeout, TimeUnit unit) 843 throws InterruptedException { 844 return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); 845 } 846 847 /** 848 * Attempts to release this lock. 849 * 850 * <p>If the number of readers is now zero then the lock 851 * is made available for write lock attempts. If the current 852 * thread does not hold this lock then {@link 853 * IllegalMonitorStateException} is thrown. 854 * 855 * @throws IllegalMonitorStateException if the current thread 856 * does not hold this lock 857 */ unlock()858 public void unlock() { 859 sync.releaseShared(1); 860 } 861 862 /** 863 * Throws {@code UnsupportedOperationException} because 864 * {@code ReadLocks} do not support conditions. 865 * 866 * @throws UnsupportedOperationException always 867 */ newCondition()868 public Condition newCondition() { 869 throw new UnsupportedOperationException(); 870 } 871 872 /** 873 * Returns a string identifying this lock, as well as its lock state. 874 * The state, in brackets, includes the String {@code "Read locks ="} 875 * followed by the number of held read locks. 876 * 877 * @return a string identifying this lock, as well as its lock state 878 */ toString()879 public String toString() { 880 int r = sync.getReadLockCount(); 881 return super.toString() + 882 "[Read locks = " + r + "]"; 883 } 884 } 885 886 /** 887 * The lock returned by method {@link ReentrantReadWriteLock#writeLock}. 888 */ 889 public static class WriteLock implements Lock, java.io.Serializable { 890 private static final long serialVersionUID = -4992448646407690164L; 891 private final Sync sync; 892 893 /** 894 * Constructor for use by subclasses. 895 * 896 * @param lock the outer lock object 897 * @throws NullPointerException if the lock is null 898 */ WriteLock(ReentrantReadWriteLock lock)899 protected WriteLock(ReentrantReadWriteLock lock) { 900 sync = lock.sync; 901 } 902 903 /** 904 * Acquires the write lock. 905 * 906 * <p>Acquires the write lock if neither the read nor write lock 907 * are held by another thread 908 * and returns immediately, setting the write lock hold count to 909 * one. 910 * 911 * <p>If the current thread already holds the write lock then the 912 * hold count is incremented by one and the method returns 913 * immediately. 914 * 915 * <p>If the lock is held by another thread then the current 916 * thread becomes disabled for thread scheduling purposes and 917 * lies dormant until the write lock has been acquired, at which 918 * time the write lock hold count is set to one. 919 */ lock()920 public void lock() { 921 sync.acquire(1); 922 } 923 924 /** 925 * Acquires the write lock unless the current thread is 926 * {@linkplain Thread#interrupt interrupted}. 927 * 928 * <p>Acquires the write lock if neither the read nor write lock 929 * are held by another thread 930 * and returns immediately, setting the write lock hold count to 931 * one. 932 * 933 * <p>If the current thread already holds this lock then the 934 * hold count is incremented by one and the method returns 935 * immediately. 936 * 937 * <p>If the lock is held by another thread then the current 938 * thread becomes disabled for thread scheduling purposes and 939 * lies dormant until one of two things happens: 940 * 941 * <ul> 942 * 943 * <li>The write lock is acquired by the current thread; or 944 * 945 * <li>Some other thread {@linkplain Thread#interrupt interrupts} 946 * the current thread. 947 * 948 * </ul> 949 * 950 * <p>If the write lock is acquired by the current thread then the 951 * lock hold count is set to one. 952 * 953 * <p>If the current thread: 954 * 955 * <ul> 956 * 957 * <li>has its interrupted status set on entry to this method; 958 * or 959 * 960 * <li>is {@linkplain Thread#interrupt interrupted} while 961 * acquiring the write lock, 962 * 963 * </ul> 964 * 965 * then {@link InterruptedException} is thrown and the current 966 * thread's interrupted status is cleared. 967 * 968 * <p>In this implementation, as this method is an explicit 969 * interruption point, preference is given to responding to 970 * the interrupt over normal or reentrant acquisition of the 971 * lock. 972 * 973 * @throws InterruptedException if the current thread is interrupted 974 */ lockInterruptibly()975 public void lockInterruptibly() throws InterruptedException { 976 sync.acquireInterruptibly(1); 977 } 978 979 /** 980 * Acquires the write lock only if it is not held by another thread 981 * at the time of invocation. 982 * 983 * <p>Acquires the write lock if neither the read nor write lock 984 * are held by another thread 985 * and returns immediately with the value {@code true}, 986 * setting the write lock hold count to one. Even when this lock has 987 * been set to use a fair ordering policy, a call to 988 * {@code tryLock()} <em>will</em> immediately acquire the 989 * lock if it is available, whether or not other threads are 990 * currently waiting for the write lock. This "barging" 991 * behavior can be useful in certain circumstances, even 992 * though it breaks fairness. If you want to honor the 993 * fairness setting for this lock, then use {@link 994 * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } 995 * which is almost equivalent (it also detects interruption). 996 * 997 * <p>If the current thread already holds this lock then the 998 * hold count is incremented by one and the method returns 999 * {@code true}. 1000 * 1001 * <p>If the lock is held by another thread then this method 1002 * will return immediately with the value {@code false}. 1003 * 1004 * @return {@code true} if the lock was free and was acquired 1005 * by the current thread, or the write lock was already held 1006 * by the current thread; and {@code false} otherwise. 1007 */ tryLock()1008 public boolean tryLock() { 1009 return sync.tryWriteLock(); 1010 } 1011 1012 /** 1013 * Acquires the write lock if it is not held by another thread 1014 * within the given waiting time and the current thread has 1015 * not been {@linkplain Thread#interrupt interrupted}. 1016 * 1017 * <p>Acquires the write lock if neither the read nor write lock 1018 * are held by another thread 1019 * and returns immediately with the value {@code true}, 1020 * setting the write lock hold count to one. If this lock has been 1021 * set to use a fair ordering policy then an available lock 1022 * <em>will not</em> be acquired if any other threads are 1023 * waiting for the write lock. This is in contrast to the {@link 1024 * #tryLock()} method. If you want a timed {@code tryLock} 1025 * that does permit barging on a fair lock then combine the 1026 * timed and un-timed forms together: 1027 * 1028 * <pre> {@code 1029 * if (lock.tryLock() || 1030 * lock.tryLock(timeout, unit)) { 1031 * ... 1032 * }}</pre> 1033 * 1034 * <p>If the current thread already holds this lock then the 1035 * hold count is incremented by one and the method returns 1036 * {@code true}. 1037 * 1038 * <p>If the lock is held by another thread then the current 1039 * thread becomes disabled for thread scheduling purposes and 1040 * lies dormant until one of three things happens: 1041 * 1042 * <ul> 1043 * 1044 * <li>The write lock is acquired by the current thread; or 1045 * 1046 * <li>Some other thread {@linkplain Thread#interrupt interrupts} 1047 * the current thread; or 1048 * 1049 * <li>The specified waiting time elapses 1050 * 1051 * </ul> 1052 * 1053 * <p>If the write lock is acquired then the value {@code true} is 1054 * returned and the write lock hold count is set to one. 1055 * 1056 * <p>If the current thread: 1057 * 1058 * <ul> 1059 * 1060 * <li>has its interrupted status set on entry to this method; 1061 * or 1062 * 1063 * <li>is {@linkplain Thread#interrupt interrupted} while 1064 * acquiring the write lock, 1065 * 1066 * </ul> 1067 * 1068 * then {@link InterruptedException} is thrown and the current 1069 * thread's interrupted status is cleared. 1070 * 1071 * <p>If the specified waiting time elapses then the value 1072 * {@code false} is returned. If the time is less than or 1073 * equal to zero, the method will not wait at all. 1074 * 1075 * <p>In this implementation, as this method is an explicit 1076 * interruption point, preference is given to responding to 1077 * the interrupt over normal or reentrant acquisition of the 1078 * lock, and over reporting the elapse of the waiting time. 1079 * 1080 * @param timeout the time to wait for the write lock 1081 * @param unit the time unit of the timeout argument 1082 * 1083 * @return {@code true} if the lock was free and was acquired 1084 * by the current thread, or the write lock was already held by the 1085 * current thread; and {@code false} if the waiting time 1086 * elapsed before the lock could be acquired. 1087 * 1088 * @throws InterruptedException if the current thread is interrupted 1089 * @throws NullPointerException if the time unit is null 1090 */ tryLock(long timeout, TimeUnit unit)1091 public boolean tryLock(long timeout, TimeUnit unit) 1092 throws InterruptedException { 1093 return sync.tryAcquireNanos(1, unit.toNanos(timeout)); 1094 } 1095 1096 /** 1097 * Attempts to release this lock. 1098 * 1099 * <p>If the current thread is the holder of this lock then 1100 * the hold count is decremented. If the hold count is now 1101 * zero then the lock is released. If the current thread is 1102 * not the holder of this lock then {@link 1103 * IllegalMonitorStateException} is thrown. 1104 * 1105 * @throws IllegalMonitorStateException if the current thread does not 1106 * hold this lock 1107 */ unlock()1108 public void unlock() { 1109 sync.release(1); 1110 } 1111 1112 /** 1113 * Returns a {@link Condition} instance for use with this 1114 * {@link Lock} instance. 1115 * <p>The returned {@link Condition} instance supports the same 1116 * usages as do the {@link Object} monitor methods ({@link 1117 * Object#wait() wait}, {@link Object#notify notify}, and {@link 1118 * Object#notifyAll notifyAll}) when used with the built-in 1119 * monitor lock. 1120 * 1121 * <ul> 1122 * 1123 * <li>If this write lock is not held when any {@link 1124 * Condition} method is called then an {@link 1125 * IllegalMonitorStateException} is thrown. (Read locks are 1126 * held independently of write locks, so are not checked or 1127 * affected. However it is essentially always an error to 1128 * invoke a condition waiting method when the current thread 1129 * has also acquired read locks, since other threads that 1130 * could unblock it will not be able to acquire the write 1131 * lock.) 1132 * 1133 * <li>When the condition {@linkplain Condition#await() waiting} 1134 * methods are called the write lock is released and, before 1135 * they return, the write lock is reacquired and the lock hold 1136 * count restored to what it was when the method was called. 1137 * 1138 * <li>If a thread is {@linkplain Thread#interrupt interrupted} while 1139 * waiting then the wait will terminate, an {@link 1140 * InterruptedException} will be thrown, and the thread's 1141 * interrupted status will be cleared. 1142 * 1143 * <li>Waiting threads are signalled in FIFO order. 1144 * 1145 * <li>The ordering of lock reacquisition for threads returning 1146 * from waiting methods is the same as for threads initially 1147 * acquiring the lock, which is in the default case not specified, 1148 * but for <em>fair</em> locks favors those threads that have been 1149 * waiting the longest. 1150 * 1151 * </ul> 1152 * 1153 * @return the Condition object 1154 */ newCondition()1155 public Condition newCondition() { 1156 return sync.newCondition(); 1157 } 1158 1159 /** 1160 * Returns a string identifying this lock, as well as its lock 1161 * state. The state, in brackets includes either the String 1162 * {@code "Unlocked"} or the String {@code "Locked by"} 1163 * followed by the {@linkplain Thread#getName name} of the owning thread. 1164 * 1165 * @return a string identifying this lock, as well as its lock state 1166 */ toString()1167 public String toString() { 1168 Thread o = sync.getOwner(); 1169 return super.toString() + ((o == null) ? 1170 "[Unlocked]" : 1171 "[Locked by thread " + o.getName() + "]"); 1172 } 1173 1174 /** 1175 * Queries if this write lock is held by the current thread. 1176 * Identical in effect to {@link 1177 * ReentrantReadWriteLock#isWriteLockedByCurrentThread}. 1178 * 1179 * @return {@code true} if the current thread holds this lock and 1180 * {@code false} otherwise 1181 * @since 1.6 1182 */ isHeldByCurrentThread()1183 public boolean isHeldByCurrentThread() { 1184 return sync.isHeldExclusively(); 1185 } 1186 1187 /** 1188 * Queries the number of holds on this write lock by the current 1189 * thread. A thread has a hold on a lock for each lock action 1190 * that is not matched by an unlock action. Identical in effect 1191 * to {@link ReentrantReadWriteLock#getWriteHoldCount}. 1192 * 1193 * @return the number of holds on this lock by the current thread, 1194 * or zero if this lock is not held by the current thread 1195 * @since 1.6 1196 */ getHoldCount()1197 public int getHoldCount() { 1198 return sync.getWriteHoldCount(); 1199 } 1200 } 1201 1202 // Instrumentation and status 1203 1204 /** 1205 * Returns {@code true} if this lock has fairness set true. 1206 * 1207 * @return {@code true} if this lock has fairness set true 1208 */ isFair()1209 public final boolean isFair() { 1210 return sync instanceof FairSync; 1211 } 1212 1213 /** 1214 * Returns the thread that currently owns the write lock, or 1215 * {@code null} if not owned. When this method is called by a 1216 * thread that is not the owner, the return value reflects a 1217 * best-effort approximation of current lock status. For example, 1218 * the owner may be momentarily {@code null} even if there are 1219 * threads trying to acquire the lock but have not yet done so. 1220 * This method is designed to facilitate construction of 1221 * subclasses that provide more extensive lock monitoring 1222 * facilities. 1223 * 1224 * @return the owner, or {@code null} if not owned 1225 */ getOwner()1226 protected Thread getOwner() { 1227 return sync.getOwner(); 1228 } 1229 1230 /** 1231 * Queries the number of read locks held for this lock. This 1232 * method is designed for use in monitoring system state, not for 1233 * synchronization control. 1234 * @return the number of read locks held 1235 */ getReadLockCount()1236 public int getReadLockCount() { 1237 return sync.getReadLockCount(); 1238 } 1239 1240 /** 1241 * Queries if the write lock is held by any thread. This method is 1242 * designed for use in monitoring system state, not for 1243 * synchronization control. 1244 * 1245 * @return {@code true} if any thread holds the write lock and 1246 * {@code false} otherwise 1247 */ isWriteLocked()1248 public boolean isWriteLocked() { 1249 return sync.isWriteLocked(); 1250 } 1251 1252 /** 1253 * Queries if the write lock is held by the current thread. 1254 * 1255 * @return {@code true} if the current thread holds the write lock and 1256 * {@code false} otherwise 1257 */ isWriteLockedByCurrentThread()1258 public boolean isWriteLockedByCurrentThread() { 1259 return sync.isHeldExclusively(); 1260 } 1261 1262 /** 1263 * Queries the number of reentrant write holds on this lock by the 1264 * current thread. A writer thread has a hold on a lock for 1265 * each lock action that is not matched by an unlock action. 1266 * 1267 * @return the number of holds on the write lock by the current thread, 1268 * or zero if the write lock is not held by the current thread 1269 */ getWriteHoldCount()1270 public int getWriteHoldCount() { 1271 return sync.getWriteHoldCount(); 1272 } 1273 1274 /** 1275 * Queries the number of reentrant read holds on this lock by the 1276 * current thread. A reader thread has a hold on a lock for 1277 * each lock action that is not matched by an unlock action. 1278 * 1279 * @return the number of holds on the read lock by the current thread, 1280 * or zero if the read lock is not held by the current thread 1281 * @since 1.6 1282 */ getReadHoldCount()1283 public int getReadHoldCount() { 1284 return sync.getReadHoldCount(); 1285 } 1286 1287 /** 1288 * Returns a collection containing threads that may be waiting to 1289 * acquire the write lock. Because the actual set of threads may 1290 * change dynamically while constructing this result, the returned 1291 * collection is only a best-effort estimate. The elements of the 1292 * returned collection are in no particular order. This method is 1293 * designed to facilitate construction of subclasses that provide 1294 * more extensive lock monitoring facilities. 1295 * 1296 * @return the collection of threads 1297 */ getQueuedWriterThreads()1298 protected Collection<Thread> getQueuedWriterThreads() { 1299 return sync.getExclusiveQueuedThreads(); 1300 } 1301 1302 /** 1303 * Returns a collection containing threads that may be waiting to 1304 * acquire the read lock. Because the actual set of threads may 1305 * change dynamically while constructing this result, the returned 1306 * collection is only a best-effort estimate. The elements of the 1307 * returned collection are in no particular order. This method is 1308 * designed to facilitate construction of subclasses that provide 1309 * more extensive lock monitoring facilities. 1310 * 1311 * @return the collection of threads 1312 */ getQueuedReaderThreads()1313 protected Collection<Thread> getQueuedReaderThreads() { 1314 return sync.getSharedQueuedThreads(); 1315 } 1316 1317 /** 1318 * Queries whether any threads are waiting to acquire the read or 1319 * write lock. Note that because cancellations may occur at any 1320 * time, a {@code true} return does not guarantee that any other 1321 * thread will ever acquire a lock. This method is designed 1322 * primarily for use in monitoring of the system state. 1323 * 1324 * @return {@code true} if there may be other threads waiting to 1325 * acquire the lock 1326 */ hasQueuedThreads()1327 public final boolean hasQueuedThreads() { 1328 return sync.hasQueuedThreads(); 1329 } 1330 1331 /** 1332 * Queries whether the given thread is waiting to acquire either 1333 * the read or write lock. Note that because cancellations may 1334 * occur at any time, a {@code true} return does not guarantee 1335 * that this thread will ever acquire a lock. This method is 1336 * designed primarily for use in monitoring of the system state. 1337 * 1338 * @param thread the thread 1339 * @return {@code true} if the given thread is queued waiting for this lock 1340 * @throws NullPointerException if the thread is null 1341 */ hasQueuedThread(Thread thread)1342 public final boolean hasQueuedThread(Thread thread) { 1343 return sync.isQueued(thread); 1344 } 1345 1346 /** 1347 * Returns an estimate of the number of threads waiting to acquire 1348 * either the read or write lock. The value is only an estimate 1349 * because the number of threads may change dynamically while this 1350 * method traverses internal data structures. This method is 1351 * designed for use in monitoring system state, not for 1352 * synchronization control. 1353 * 1354 * @return the estimated number of threads waiting for this lock 1355 */ getQueueLength()1356 public final int getQueueLength() { 1357 return sync.getQueueLength(); 1358 } 1359 1360 /** 1361 * Returns a collection containing threads that may be waiting to 1362 * acquire either the read or write lock. Because the actual set 1363 * of threads may change dynamically while constructing this 1364 * result, the returned collection is only a best-effort estimate. 1365 * The elements of the returned collection are in no particular 1366 * order. This method is designed to facilitate construction of 1367 * subclasses that provide more extensive monitoring facilities. 1368 * 1369 * @return the collection of threads 1370 */ getQueuedThreads()1371 protected Collection<Thread> getQueuedThreads() { 1372 return sync.getQueuedThreads(); 1373 } 1374 1375 /** 1376 * Queries whether any threads are waiting on the given condition 1377 * associated with the write lock. Note that because timeouts and 1378 * interrupts may occur at any time, a {@code true} return does 1379 * not guarantee that a future {@code signal} will awaken any 1380 * threads. This method is designed primarily for use in 1381 * monitoring of the system state. 1382 * 1383 * @param condition the condition 1384 * @return {@code true} if there are any waiting threads 1385 * @throws IllegalMonitorStateException if this lock is not held 1386 * @throws IllegalArgumentException if the given condition is 1387 * not associated with this lock 1388 * @throws NullPointerException if the condition is null 1389 */ hasWaiters(Condition condition)1390 public boolean hasWaiters(Condition condition) { 1391 if (condition == null) 1392 throw new NullPointerException(); 1393 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) 1394 throw new IllegalArgumentException("not owner"); 1395 return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition); 1396 } 1397 1398 /** 1399 * Returns an estimate of the number of threads waiting on the 1400 * given condition associated with the write lock. Note that because 1401 * timeouts and interrupts may occur at any time, the estimate 1402 * serves only as an upper bound on the actual number of waiters. 1403 * This method is designed for use in monitoring of the system 1404 * state, not for synchronization control. 1405 * 1406 * @param condition the condition 1407 * @return the estimated number of waiting threads 1408 * @throws IllegalMonitorStateException if this lock is not held 1409 * @throws IllegalArgumentException if the given condition is 1410 * not associated with this lock 1411 * @throws NullPointerException if the condition is null 1412 */ getWaitQueueLength(Condition condition)1413 public int getWaitQueueLength(Condition condition) { 1414 if (condition == null) 1415 throw new NullPointerException(); 1416 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) 1417 throw new IllegalArgumentException("not owner"); 1418 return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition); 1419 } 1420 1421 /** 1422 * Returns a collection containing those threads that may be 1423 * waiting on the given condition associated with the write lock. 1424 * Because the actual set of threads may change dynamically while 1425 * constructing this result, the returned collection is only a 1426 * best-effort estimate. The elements of the returned collection 1427 * are in no particular order. This method is designed to 1428 * facilitate construction of subclasses that provide more 1429 * extensive condition monitoring facilities. 1430 * 1431 * @param condition the condition 1432 * @return the collection of threads 1433 * @throws IllegalMonitorStateException if this lock is not held 1434 * @throws IllegalArgumentException if the given condition is 1435 * not associated with this lock 1436 * @throws NullPointerException if the condition is null 1437 */ getWaitingThreads(Condition condition)1438 protected Collection<Thread> getWaitingThreads(Condition condition) { 1439 if (condition == null) 1440 throw new NullPointerException(); 1441 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) 1442 throw new IllegalArgumentException("not owner"); 1443 return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition); 1444 } 1445 1446 /** 1447 * Returns a string identifying this lock, as well as its lock state. 1448 * The state, in brackets, includes the String {@code "Write locks ="} 1449 * followed by the number of reentrantly held write locks, and the 1450 * String {@code "Read locks ="} followed by the number of held 1451 * read locks. 1452 * 1453 * @return a string identifying this lock, as well as its lock state 1454 */ toString()1455 public String toString() { 1456 int c = sync.getCount(); 1457 int w = Sync.exclusiveCount(c); 1458 int r = Sync.sharedCount(c); 1459 1460 return super.toString() + 1461 "[Write locks = " + w + ", Read locks = " + r + "]"; 1462 } 1463 1464 /** 1465 * Returns the thread id for the given thread. We must access 1466 * this directly rather than via method Thread.getId() because 1467 * getId() is not final, and has been known to be overridden in 1468 * ways that do not preserve unique mappings. 1469 */ getThreadId(Thread thread)1470 static final long getThreadId(Thread thread) { 1471 return U.getLongVolatile(thread, TID); 1472 } 1473 1474 // Unsafe mechanics 1475 private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); 1476 private static final long TID; 1477 static { 1478 try { 1479 TID = U.objectFieldOffset 1480 (Thread.class.getDeclaredField("tid")); 1481 } catch (ReflectiveOperationException e) { 1482 throw new Error(e); 1483 } 1484 } 1485 1486 } 1487