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