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