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