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