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