0001 /*
0002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0003 *
0004 * This code is free software; you can redistribute it and/or modify it
0005 * under the terms of the GNU General Public License version 2 only, as
0006 * published by the Free Software Foundation. Sun designates this
0007 * particular file as subject to the "Classpath" exception as provided
0008 * by Sun in the LICENSE file that accompanied this code.
0009 *
0010 * This code is distributed in the hope that it will be useful, but WITHOUT
0011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0013 * version 2 for more details (a copy is included in the LICENSE file that
0014 * accompanied this code).
0015 *
0016 * You should have received a copy of the GNU General Public License version
0017 * 2 along with this work; if not, write to the Free Software Foundation,
0018 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0019 *
0020 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0021 * CA 95054 USA or visit www.sun.com if you need additional information or
0022 * have any questions.
0023 */
0024
0025 /*
0026 * This file is available under and governed by the GNU General Public
0027 * License version 2 only, as published by the Free Software Foundation.
0028 * However, the following notice accompanied the original version of this
0029 * file:
0030 *
0031 * Written by Doug Lea with assistance from members of JCP JSR-166
0032 * Expert Group and released to the public domain, as explained at
0033 * http://creativecommons.org/licenses/publicdomain
0034 */
0035
0036 package java.util.concurrent.locks;
0037
0038 import java.util.concurrent.*;
0039 import java.util.concurrent.atomic.*;
0040 import java.util.*;
0041
0042 /**
0043 * An implementation of {@link ReadWriteLock} supporting similar
0044 * semantics to {@link ReentrantLock}.
0045 * <p>This class has the following properties:
0046 *
0047 * <ul>
0048 * <li><b>Acquisition order</b>
0049 *
0050 * <p> This class does not impose a reader or writer preference
0051 * ordering for lock access. However, it does support an optional
0052 * <em>fairness</em> policy.
0053 *
0054 * <dl>
0055 * <dt><b><i>Non-fair mode (default)</i></b>
0056 * <dd>When constructed as non-fair (the default), the order of entry
0057 * to the read and write lock is unspecified, subject to reentrancy
0058 * constraints. A nonfair lock that is continuously contended may
0059 * indefinitely postpone one or more reader or writer threads, but
0060 * will normally have higher throughput than a fair lock.
0061 * <p>
0062 *
0063 * <dt><b><i>Fair mode</i></b>
0064 * <dd> When constructed as fair, threads contend for entry using an
0065 * approximately arrival-order policy. When the currently held lock
0066 * is released either the longest-waiting single writer thread will
0067 * be assigned the write lock, or if there is a group of reader threads
0068 * waiting longer than all waiting writer threads, that group will be
0069 * assigned the read lock.
0070 *
0071 * <p>A thread that tries to acquire a fair read lock (non-reentrantly)
0072 * will block if either the write lock is held, or there is a waiting
0073 * writer thread. The thread will not acquire the read lock until
0074 * after the oldest currently waiting writer thread has acquired and
0075 * released the write lock. Of course, if a waiting writer abandons
0076 * its wait, leaving one or more reader threads as the longest waiters
0077 * in the queue with the write lock free, then those readers will be
0078 * assigned the read lock.
0079 *
0080 * <p>A thread that tries to acquire a fair write lock (non-reentrantly)
0081 * will block unless both the read lock and write lock are free (which
0082 * implies there are no waiting threads). (Note that the non-blocking
0083 * {@link ReadLock#tryLock()} and {@link WriteLock#tryLock()} methods
0084 * do not honor this fair setting and will acquire the lock if it is
0085 * possible, regardless of waiting threads.)
0086 * <p>
0087 * </dl>
0088 *
0089 * <li><b>Reentrancy</b>
0090 *
0091 * <p>This lock allows both readers and writers to reacquire read or
0092 * write locks in the style of a {@link ReentrantLock}. Non-reentrant
0093 * readers are not allowed until all write locks held by the writing
0094 * thread have been released.
0095 *
0096 * <p>Additionally, a writer can acquire the read lock, but not
0097 * vice-versa. Among other applications, reentrancy can be useful
0098 * when write locks are held during calls or callbacks to methods that
0099 * perform reads under read locks. If a reader tries to acquire the
0100 * write lock it will never succeed.
0101 *
0102 * <li><b>Lock downgrading</b>
0103 * <p>Reentrancy also allows downgrading from the write lock to a read lock,
0104 * by acquiring the write lock, then the read lock and then releasing the
0105 * write lock. However, upgrading from a read lock to the write lock is
0106 * <b>not</b> possible.
0107 *
0108 * <li><b>Interruption of lock acquisition</b>
0109 * <p>The read lock and write lock both support interruption during lock
0110 * acquisition.
0111 *
0112 * <li><b>{@link Condition} support</b>
0113 * <p>The write lock provides a {@link Condition} implementation that
0114 * behaves in the same way, with respect to the write lock, as the
0115 * {@link Condition} implementation provided by
0116 * {@link ReentrantLock#newCondition} does for {@link ReentrantLock}.
0117 * This {@link Condition} can, of course, only be used with the write lock.
0118 *
0119 * <p>The read lock does not support a {@link Condition} and
0120 * {@code readLock().newCondition()} throws
0121 * {@code UnsupportedOperationException}.
0122 *
0123 * <li><b>Instrumentation</b>
0124 * <p>This class supports methods to determine whether locks
0125 * are held or contended. These methods are designed for monitoring
0126 * system state, not for synchronization control.
0127 * </ul>
0128 *
0129 * <p>Serialization of this class behaves in the same way as built-in
0130 * locks: a deserialized lock is in the unlocked state, regardless of
0131 * its state when serialized.
0132 *
0133 * <p><b>Sample usages</b>. Here is a code sketch showing how to perform
0134 * lock downgrading after updating a cache (exception handling is
0135 * particularly tricky when handling multiple locks in a non-nested
0136 * fashion):
0137 *
0138 * <pre> {@code
0139 * class CachedData {
0140 * Object data;
0141 * volatile boolean cacheValid;
0142 * final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
0143 *
0144 * void processCachedData() {
0145 * rwl.readLock().lock();
0146 * if (!cacheValid) {
0147 * // Must release read lock before acquiring write lock
0148 * rwl.readLock().unlock();
0149 * rwl.writeLock().lock();
0150 * try {
0151 * // Recheck state because another thread might have
0152 * // acquired write lock and changed state before we did.
0153 * if (!cacheValid) {
0154 * data = ...
0155 * cacheValid = true;
0156 * }
0157 * // Downgrade by acquiring read lock before releasing write lock
0158 * rwl.readLock().lock();
0159 * } finally {
0160 * rwl.writeLock().unlock(); // Unlock write, still hold read
0161 * }
0162 * }
0163 *
0164 * try {
0165 * use(data);
0166 * } finally {
0167 * rwl.readLock().unlock();
0168 * }
0169 * }
0170 * }}</pre>
0171 *
0172 * ReentrantReadWriteLocks can be used to improve concurrency in some
0173 * uses of some kinds of Collections. This is typically worthwhile
0174 * only when the collections are expected to be large, accessed by
0175 * more reader threads than writer threads, and entail operations with
0176 * overhead that outweighs synchronization overhead. For example, here
0177 * is a class using a TreeMap that is expected to be large and
0178 * concurrently accessed.
0179 *
0180 * <pre>{@code
0181 * class RWDictionary {
0182 * private final Map<String, Data> m = new TreeMap<String, Data>();
0183 * private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
0184 * private final Lock r = rwl.readLock();
0185 * private final Lock w = rwl.writeLock();
0186 *
0187 * public Data get(String key) {
0188 * r.lock();
0189 * try { return m.get(key); }
0190 * finally { r.unlock(); }
0191 * }
0192 * public String[] allKeys() {
0193 * r.lock();
0194 * try { return m.keySet().toArray(); }
0195 * finally { r.unlock(); }
0196 * }
0197 * public Data put(String key, Data value) {
0198 * w.lock();
0199 * try { return m.put(key, value); }
0200 * finally { w.unlock(); }
0201 * }
0202 * public void clear() {
0203 * w.lock();
0204 * try { m.clear(); }
0205 * finally { w.unlock(); }
0206 * }
0207 * }}</pre>
0208 *
0209 * <h3>Implementation Notes</h3>
0210 *
0211 * <p>This lock supports a maximum of 65535 recursive write locks
0212 * and 65535 read locks. Attempts to exceed these limits result in
0213 * {@link Error} throws from locking methods.
0214 *
0215 * @since 1.5
0216 * @author Doug Lea
0217 *
0218 */
0219 public class ReentrantReadWriteLock implements ReadWriteLock,
0220 java.io.Serializable {
0221 private static final long serialVersionUID = -6992448646407690164L;
0222 /** Inner class providing readlock */
0223 private final ReentrantReadWriteLock.ReadLock readerLock;
0224 /** Inner class providing writelock */
0225 private final ReentrantReadWriteLock.WriteLock writerLock;
0226 /** Performs all synchronization mechanics */
0227 private final Sync sync;
0228
0229 /**
0230 * Creates a new {@code ReentrantReadWriteLock} with
0231 * default (nonfair) ordering properties.
0232 */
0233 public ReentrantReadWriteLock() {
0234 this (false);
0235 }
0236
0237 /**
0238 * Creates a new {@code ReentrantReadWriteLock} with
0239 * the given fairness policy.
0240 *
0241 * @param fair {@code true} if this lock should use a fair ordering policy
0242 */
0243 public ReentrantReadWriteLock(boolean fair) {
0244 sync = (fair) ? new FairSync() : new NonfairSync();
0245 readerLock = new ReadLock(this );
0246 writerLock = new WriteLock(this );
0247 }
0248
0249 public ReentrantReadWriteLock.WriteLock writeLock() {
0250 return writerLock;
0251 }
0252
0253 public ReentrantReadWriteLock.ReadLock readLock() {
0254 return readerLock;
0255 }
0256
0257 /**
0258 * Synchronization implementation for ReentrantReadWriteLock.
0259 * Subclassed into fair and nonfair versions.
0260 */
0261 static abstract class Sync extends AbstractQueuedSynchronizer {
0262 private static final long serialVersionUID = 6317671515068378041L;
0263
0264 /*
0265 * Read vs write count extraction constants and functions.
0266 * Lock state is logically divided into two shorts: The lower
0267 * one representing the exclusive (writer) lock hold count,
0268 * and the upper the shared (reader) hold count.
0269 */
0270
0271 static final int SHARED_SHIFT = 16;
0272 static final int SHARED_UNIT = (1 << SHARED_SHIFT);
0273 static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1;
0274 static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
0275
0276 /** Returns the number of shared holds represented in count */
0277 static int sharedCount(int c) {
0278 return c >>> SHARED_SHIFT;
0279 }
0280
0281 /** Returns the number of exclusive holds represented in count */
0282 static int exclusiveCount(int c) {
0283 return c & EXCLUSIVE_MASK;
0284 }
0285
0286 /**
0287 * A counter for per-thread read hold counts.
0288 * Maintained as a ThreadLocal; cached in cachedHoldCounter
0289 */
0290 static final class HoldCounter {
0291 int count;
0292 // Use id, not reference, to avoid garbage retention
0293 final long tid = Thread.currentThread().getId();
0294
0295 /** Decrement if positive; return previous value */
0296 int tryDecrement() {
0297 int c = count;
0298 if (c > 0)
0299 count = c - 1;
0300 return c;
0301 }
0302 }
0303
0304 /**
0305 * ThreadLocal subclass. Easiest to explicitly define for sake
0306 * of deserialization mechanics.
0307 */
0308 static final class ThreadLocalHoldCounter extends
0309 ThreadLocal<HoldCounter> {
0310 public HoldCounter initialValue() {
0311 return new HoldCounter();
0312 }
0313 }
0314
0315 /**
0316 * The number of read locks held by current thread.
0317 * Initialized only in constructor and readObject.
0318 */
0319 transient ThreadLocalHoldCounter readHolds;
0320
0321 /**
0322 * The hold count of the last thread to successfully acquire
0323 * readLock. This saves ThreadLocal lookup in the common case
0324 * where the next thread to release is the last one to
0325 * acquire. This is non-volatile since it is just used
0326 * as a heuristic, and would be great for threads to cache.
0327 */
0328 transient HoldCounter cachedHoldCounter;
0329
0330 Sync() {
0331 readHolds = new ThreadLocalHoldCounter();
0332 setState(getState()); // ensures visibility of readHolds
0333 }
0334
0335 /*
0336 * Acquires and releases use the same code for fair and
0337 * nonfair locks, but differ in whether/how they allow barging
0338 * when queues are non-empty.
0339 */
0340
0341 /**
0342 * Returns true if the current thread, when trying to acquire
0343 * the read lock, and otherwise eligible to do so, should block
0344 * because of policy for overtaking other waiting threads.
0345 */
0346 abstract boolean readerShouldBlock();
0347
0348 /**
0349 * Returns true if the current thread, when trying to acquire
0350 * the write lock, and otherwise eligible to do so, should block
0351 * because of policy for overtaking other waiting threads.
0352 */
0353 abstract boolean writerShouldBlock();
0354
0355 /*
0356 * Note that tryRelease and tryAcquire can be called by
0357 * Conditions. So it is possible that their arguments contain
0358 * both read and write holds that are all released during a
0359 * condition wait and re-established in tryAcquire.
0360 */
0361
0362 protected final boolean tryRelease(int releases) {
0363 if (!isHeldExclusively())
0364 throw new IllegalMonitorStateException();
0365 int nextc = getState() - releases;
0366 boolean free = exclusiveCount(nextc) == 0;
0367 if (free)
0368 setExclusiveOwnerThread(null);
0369 setState(nextc);
0370 return free;
0371 }
0372
0373 protected final boolean tryAcquire(int acquires) {
0374 /*
0375 * Walkthrough:
0376 * 1. If read count nonzero or write count nonzero
0377 * and owner is a different thread, fail.
0378 * 2. If count would saturate, fail. (This can only
0379 * happen if count is already nonzero.)
0380 * 3. Otherwise, this thread is eligible for lock if
0381 * it is either a reentrant acquire or
0382 * queue policy allows it. If so, update state
0383 * and set owner.
0384 */
0385 Thread current = Thread.currentThread();
0386 int c = getState();
0387 int w = exclusiveCount(c);
0388 if (c != 0) {
0389 // (Note: if c != 0 and w == 0 then shared count != 0)
0390 if (w == 0 || current != getExclusiveOwnerThread())
0391 return false;
0392 if (w + exclusiveCount(acquires) > MAX_COUNT)
0393 throw new Error("Maximum lock count exceeded");
0394 // Reentrant acquire
0395 setState(c + acquires);
0396 return true;
0397 }
0398 if (writerShouldBlock()
0399 || !compareAndSetState(c, c + acquires))
0400 return false;
0401 setExclusiveOwnerThread(current);
0402 return true;
0403 }
0404
0405 protected final boolean tryReleaseShared(int unused) {
0406 HoldCounter rh = cachedHoldCounter;
0407 Thread current = Thread.currentThread();
0408 if (rh == null || rh.tid != current.getId())
0409 rh = readHolds.get();
0410 if (rh.tryDecrement() <= 0)
0411 throw new IllegalMonitorStateException();
0412 for (;;) {
0413 int c = getState();
0414 int nextc = c - SHARED_UNIT;
0415 if (compareAndSetState(c, nextc))
0416 return nextc == 0;
0417 }
0418 }
0419
0420 protected final int tryAcquireShared(int unused) {
0421 /*
0422 * Walkthrough:
0423 * 1. If write lock held by another thread, fail.
0424 * 2. If count saturated, throw error.
0425 * 3. Otherwise, this thread is eligible for
0426 * lock wrt state, so ask if it should block
0427 * because of queue policy. If not, try
0428 * to grant by CASing state and updating count.
0429 * Note that step does not check for reentrant
0430 * acquires, which is postponed to full version
0431 * to avoid having to check hold count in
0432 * the more typical non-reentrant case.
0433 * 4. If step 3 fails either because thread
0434 * apparently not eligible or CAS fails,
0435 * chain to version with full retry loop.
0436 */
0437 Thread current = Thread.currentThread();
0438 int c = getState();
0439 if (exclusiveCount(c) != 0
0440 && getExclusiveOwnerThread() != current)
0441 return -1;
0442 if (sharedCount(c) == MAX_COUNT)
0443 throw new Error("Maximum lock count exceeded");
0444 if (!readerShouldBlock()
0445 && compareAndSetState(c, c + SHARED_UNIT)) {
0446 HoldCounter rh = cachedHoldCounter;
0447 if (rh == null || rh.tid != current.getId())
0448 cachedHoldCounter = rh = readHolds.get();
0449 rh.count++;
0450 return 1;
0451 }
0452 return fullTryAcquireShared(current);
0453 }
0454
0455 /**
0456 * Full version of acquire for reads, that handles CAS misses
0457 * and reentrant reads not dealt with in tryAcquireShared.
0458 */
0459 final int fullTryAcquireShared(Thread current) {
0460 /*
0461 * This code is in part redundant with that in
0462 * tryAcquireShared but is simpler overall by not
0463 * complicating tryAcquireShared with interactions between
0464 * retries and lazily reading hold counts.
0465 */
0466 HoldCounter rh = cachedHoldCounter;
0467 if (rh == null || rh.tid != current.getId())
0468 rh = readHolds.get();
0469 for (;;) {
0470 int c = getState();
0471 int w = exclusiveCount(c);
0472 if ((w != 0 && getExclusiveOwnerThread() != current)
0473 || ((rh.count | w) == 0 && readerShouldBlock()))
0474 return -1;
0475 if (sharedCount(c) == MAX_COUNT)
0476 throw new Error("Maximum lock count exceeded");
0477 if (compareAndSetState(c, c + SHARED_UNIT)) {
0478 cachedHoldCounter = rh; // cache for release
0479 rh.count++;
0480 return 1;
0481 }
0482 }
0483 }
0484
0485 /**
0486 * Performs tryLock for write, enabling barging in both modes.
0487 * This is identical in effect to tryAcquire except for lack
0488 * of calls to writerShouldBlock
0489 */
0490 final boolean tryWriteLock() {
0491 Thread current = Thread.currentThread();
0492 int c = getState();
0493 if (c != 0) {
0494 int w = exclusiveCount(c);
0495 if (w == 0 || current != getExclusiveOwnerThread())
0496 return false;
0497 if (w == MAX_COUNT)
0498 throw new Error("Maximum lock count exceeded");
0499 }
0500 if (!compareAndSetState(c, c + 1))
0501 return false;
0502 setExclusiveOwnerThread(current);
0503 return true;
0504 }
0505
0506 /**
0507 * Performs tryLock for read, enabling barging in both modes.
0508 * This is identical in effect to tryAcquireShared except for
0509 * lack of calls to readerShouldBlock
0510 */
0511 final boolean tryReadLock() {
0512 Thread current = Thread.currentThread();
0513 for (;;) {
0514 int c = getState();
0515 if (exclusiveCount(c) != 0
0516 && getExclusiveOwnerThread() != current)
0517 return false;
0518 if (sharedCount(c) == MAX_COUNT)
0519 throw new Error("Maximum lock count exceeded");
0520 if (compareAndSetState(c, c + SHARED_UNIT)) {
0521 HoldCounter rh = cachedHoldCounter;
0522 if (rh == null || rh.tid != current.getId())
0523 cachedHoldCounter = rh = readHolds.get();
0524 rh.count++;
0525 return true;
0526 }
0527 }
0528 }
0529
0530 protected final boolean isHeldExclusively() {
0531 // While we must in general read state before owner,
0532 // we don't need to do so to check if current thread is owner
0533 return getExclusiveOwnerThread() == Thread.currentThread();
0534 }
0535
0536 // Methods relayed to outer class
0537
0538 final ConditionObject newCondition() {
0539 return new ConditionObject();
0540 }
0541
0542 final Thread getOwner() {
0543 // Must read state before owner to ensure memory consistency
0544 return ((exclusiveCount(getState()) == 0) ? null
0545 : getExclusiveOwnerThread());
0546 }
0547
0548 final int getReadLockCount() {
0549 return sharedCount(getState());
0550 }
0551
0552 final boolean isWriteLocked() {
0553 return exclusiveCount(getState()) != 0;
0554 }
0555
0556 final int getWriteHoldCount() {
0557 return isHeldExclusively() ? exclusiveCount(getState()) : 0;
0558 }
0559
0560 final int getReadHoldCount() {
0561 return getReadLockCount() == 0 ? 0 : readHolds.get().count;
0562 }
0563
0564 /**
0565 * Reconstitute this lock instance from a stream
0566 * @param s the stream
0567 */
0568 private void readObject(java.io.ObjectInputStream s)
0569 throws java.io.IOException, ClassNotFoundException {
0570 s.defaultReadObject();
0571 readHolds = new ThreadLocalHoldCounter();
0572 setState(0); // reset to unlocked state
0573 }
0574
0575 final int getCount() {
0576 return getState();
0577 }
0578 }
0579
0580 /**
0581 * Nonfair version of Sync
0582 */
0583 final static class NonfairSync extends Sync {
0584 private static final long serialVersionUID = -8159625535654395037L;
0585
0586 final boolean writerShouldBlock() {
0587 return false; // writers can always barge
0588 }
0589
0590 final boolean readerShouldBlock() {
0591 /* As a heuristic to avoid indefinite writer starvation,
0592 * block if the thread that momentarily appears to be head
0593 * of queue, if one exists, is a waiting writer. This is
0594 * only a probabilistic effect since a new reader will not
0595 * block if there is a waiting writer behind other enabled
0596 * readers that have not yet drained from the queue.
0597 */
0598 return apparentlyFirstQueuedIsExclusive();
0599 }
0600 }
0601
0602 /**
0603 * Fair version of Sync
0604 */
0605 final static class FairSync extends Sync {
0606 private static final long serialVersionUID = -2274990926593161451L;
0607
0608 final boolean writerShouldBlock() {
0609 return hasQueuedPredecessors();
0610 }
0611
0612 final boolean readerShouldBlock() {
0613 return hasQueuedPredecessors();
0614 }
0615 }
0616
0617 /**
0618 * The lock returned by method {@link ReentrantReadWriteLock#readLock}.
0619 */
0620 public static class ReadLock implements Lock, java.io.Serializable {
0621 private static final long serialVersionUID = -5992448646407690164L;
0622 private final Sync sync;
0623
0624 /**
0625 * Constructor for use by subclasses
0626 *
0627 * @param lock the outer lock object
0628 * @throws NullPointerException if the lock is null
0629 */
0630 protected ReadLock(ReentrantReadWriteLock lock) {
0631 sync = lock.sync;
0632 }
0633
0634 /**
0635 * Acquires the read lock.
0636 *
0637 * <p>Acquires the read lock if the write lock is not held by
0638 * another thread and returns immediately.
0639 *
0640 * <p>If the write lock is held by another thread then
0641 * the current thread becomes disabled for thread scheduling
0642 * purposes and lies dormant until the read lock has been acquired.
0643 */
0644 public void lock() {
0645 sync.acquireShared(1);
0646 }
0647
0648 /**
0649 * Acquires the read lock unless the current thread is
0650 * {@linkplain Thread#interrupt interrupted}.
0651 *
0652 * <p>Acquires the read lock if the write lock is not held
0653 * by another thread and returns immediately.
0654 *
0655 * <p>If the write lock is held by another thread then the
0656 * current thread becomes disabled for thread scheduling
0657 * purposes and lies dormant until one of two things happens:
0658 *
0659 * <ul>
0660 *
0661 * <li>The read lock is acquired by the current thread; or
0662 *
0663 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
0664 * the current thread.
0665 *
0666 * </ul>
0667 *
0668 * <p>If the current thread:
0669 *
0670 * <ul>
0671 *
0672 * <li>has its interrupted status set on entry to this method; or
0673 *
0674 * <li>is {@linkplain Thread#interrupt interrupted} while
0675 * acquiring the read lock,
0676 *
0677 * </ul>
0678 *
0679 * then {@link InterruptedException} is thrown and the current
0680 * thread's interrupted status is cleared.
0681 *
0682 * <p>In this implementation, as this method is an explicit
0683 * interruption point, preference is given to responding to
0684 * the interrupt over normal or reentrant acquisition of the
0685 * lock.
0686 *
0687 * @throws InterruptedException if the current thread is interrupted
0688 */
0689 public void lockInterruptibly() throws InterruptedException {
0690 sync.acquireSharedInterruptibly(1);
0691 }
0692
0693 /**
0694 * Acquires the read lock only if the write lock is not held by
0695 * another thread at the time of invocation.
0696 *
0697 * <p>Acquires the read lock if the write lock is not held by
0698 * another thread and returns immediately with the value
0699 * {@code true}. Even when this lock has been set to use a
0700 * fair ordering policy, a call to {@code tryLock()}
0701 * <em>will</em> immediately acquire the read lock if it is
0702 * available, whether or not other threads are currently
0703 * waiting for the read lock. This "barging" behavior
0704 * can be useful in certain circumstances, even though it
0705 * breaks fairness. If you want to honor the fairness setting
0706 * for this lock, then use {@link #tryLock(long, TimeUnit)
0707 * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent
0708 * (it also detects interruption).
0709 *
0710 * <p>If the write lock is held by another thread then
0711 * this method will return immediately with the value
0712 * {@code false}.
0713 *
0714 * @return {@code true} if the read lock was acquired
0715 */
0716 public boolean tryLock() {
0717 return sync.tryReadLock();
0718 }
0719
0720 /**
0721 * Acquires the read lock if the write lock is not held by
0722 * another thread within the given waiting time and the
0723 * current thread has not been {@linkplain Thread#interrupt
0724 * interrupted}.
0725 *
0726 * <p>Acquires the read lock if the write lock is not held by
0727 * another thread and returns immediately with the value
0728 * {@code true}. If this lock has been set to use a fair
0729 * ordering policy then an available lock <em>will not</em> be
0730 * acquired if any other threads are waiting for the
0731 * lock. This is in contrast to the {@link #tryLock()}
0732 * method. If you want a timed {@code tryLock} that does
0733 * permit barging on a fair lock then combine the timed and
0734 * un-timed forms together:
0735 *
0736 * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
0737 * </pre>
0738 *
0739 * <p>If the write lock is held by another thread then the
0740 * current thread becomes disabled for thread scheduling
0741 * purposes and lies dormant until one of three things happens:
0742 *
0743 * <ul>
0744 *
0745 * <li>The read lock is acquired by the current thread; or
0746 *
0747 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
0748 * the current thread; or
0749 *
0750 * <li>The specified waiting time elapses.
0751 *
0752 * </ul>
0753 *
0754 * <p>If the read lock is acquired then the value {@code true} is
0755 * returned.
0756 *
0757 * <p>If the current thread:
0758 *
0759 * <ul>
0760 *
0761 * <li>has its interrupted status set on entry to this method; or
0762 *
0763 * <li>is {@linkplain Thread#interrupt interrupted} while
0764 * acquiring the read lock,
0765 *
0766 * </ul> then {@link InterruptedException} is thrown and the
0767 * current thread's interrupted status is cleared.
0768 *
0769 * <p>If the specified waiting time elapses then the value
0770 * {@code false} is returned. If the time is less than or
0771 * equal to zero, the method will not wait at all.
0772 *
0773 * <p>In this implementation, as this method is an explicit
0774 * interruption point, preference is given to responding to
0775 * the interrupt over normal or reentrant acquisition of the
0776 * lock, and over reporting the elapse of the waiting time.
0777 *
0778 * @param timeout the time to wait for the read lock
0779 * @param unit the time unit of the timeout argument
0780 * @return {@code true} if the read lock was acquired
0781 * @throws InterruptedException if the current thread is interrupted
0782 * @throws NullPointerException if the time unit is null
0783 *
0784 */
0785 public boolean tryLock(long timeout, TimeUnit unit)
0786 throws InterruptedException {
0787 return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
0788 }
0789
0790 /**
0791 * Attempts to release this lock.
0792 *
0793 * <p> If the number of readers is now zero then the lock
0794 * is made available for write lock attempts.
0795 */
0796 public void unlock() {
0797 sync.releaseShared(1);
0798 }
0799
0800 /**
0801 * Throws {@code UnsupportedOperationException} because
0802 * {@code ReadLocks} do not support conditions.
0803 *
0804 * @throws UnsupportedOperationException always
0805 */
0806 public Condition newCondition() {
0807 throw new UnsupportedOperationException();
0808 }
0809
0810 /**
0811 * Returns a string identifying this lock, as well as its lock state.
0812 * The state, in brackets, includes the String {@code "Read locks ="}
0813 * followed by the number of held read locks.
0814 *
0815 * @return a string identifying this lock, as well as its lock state
0816 */
0817 public String toString() {
0818 int r = sync.getReadLockCount();
0819 return super .toString() + "[Read locks = " + r + "]";
0820 }
0821 }
0822
0823 /**
0824 * The lock returned by method {@link ReentrantReadWriteLock#writeLock}.
0825 */
0826 public static class WriteLock implements Lock, java.io.Serializable {
0827 private static final long serialVersionUID = -4992448646407690164L;
0828 private final Sync sync;
0829
0830 /**
0831 * Constructor for use by subclasses
0832 *
0833 * @param lock the outer lock object
0834 * @throws NullPointerException if the lock is null
0835 */
0836 protected WriteLock(ReentrantReadWriteLock lock) {
0837 sync = lock.sync;
0838 }
0839
0840 /**
0841 * Acquires the write lock.
0842 *
0843 * <p>Acquires the write lock if neither the read nor write lock
0844 * are held by another thread
0845 * and returns immediately, setting the write lock hold count to
0846 * one.
0847 *
0848 * <p>If the current thread already holds the write lock then the
0849 * hold count is incremented by one and the method returns
0850 * immediately.
0851 *
0852 * <p>If the lock is held by another thread then the current
0853 * thread becomes disabled for thread scheduling purposes and
0854 * lies dormant until the write lock has been acquired, at which
0855 * time the write lock hold count is set to one.
0856 */
0857 public void lock() {
0858 sync.acquire(1);
0859 }
0860
0861 /**
0862 * Acquires the write lock unless the current thread is
0863 * {@linkplain Thread#interrupt interrupted}.
0864 *
0865 * <p>Acquires the write lock if neither the read nor write lock
0866 * are held by another thread
0867 * and returns immediately, setting the write lock hold count to
0868 * one.
0869 *
0870 * <p>If the current thread already holds this lock then the
0871 * hold count is incremented by one and the method returns
0872 * immediately.
0873 *
0874 * <p>If the lock is held by another thread then the current
0875 * thread becomes disabled for thread scheduling purposes and
0876 * lies dormant until one of two things happens:
0877 *
0878 * <ul>
0879 *
0880 * <li>The write lock is acquired by the current thread; or
0881 *
0882 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
0883 * the current thread.
0884 *
0885 * </ul>
0886 *
0887 * <p>If the write lock is acquired by the current thread then the
0888 * lock hold count is set to one.
0889 *
0890 * <p>If the current thread:
0891 *
0892 * <ul>
0893 *
0894 * <li>has its interrupted status set on entry to this method;
0895 * or
0896 *
0897 * <li>is {@linkplain Thread#interrupt interrupted} while
0898 * acquiring the write lock,
0899 *
0900 * </ul>
0901 *
0902 * then {@link InterruptedException} is thrown and the current
0903 * thread's interrupted status is cleared.
0904 *
0905 * <p>In this implementation, as this method is an explicit
0906 * interruption point, preference is given to responding to
0907 * the interrupt over normal or reentrant acquisition of the
0908 * lock.
0909 *
0910 * @throws InterruptedException if the current thread is interrupted
0911 */
0912 public void lockInterruptibly() throws InterruptedException {
0913 sync.acquireInterruptibly(1);
0914 }
0915
0916 /**
0917 * Acquires the write lock only if it is not held by another thread
0918 * at the time of invocation.
0919 *
0920 * <p>Acquires the write lock if neither the read nor write lock
0921 * are held by another thread
0922 * and returns immediately with the value {@code true},
0923 * setting the write lock hold count to one. Even when this lock has
0924 * been set to use a fair ordering policy, a call to
0925 * {@code tryLock()} <em>will</em> immediately acquire the
0926 * lock if it is available, whether or not other threads are
0927 * currently waiting for the write lock. This "barging"
0928 * behavior can be useful in certain circumstances, even
0929 * though it breaks fairness. If you want to honor the
0930 * fairness setting for this lock, then use {@link
0931 * #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) }
0932 * which is almost equivalent (it also detects interruption).
0933 *
0934 * <p> If the current thread already holds this lock then the
0935 * hold count is incremented by one and the method returns
0936 * {@code true}.
0937 *
0938 * <p>If the lock is held by another thread then this method
0939 * will return immediately with the value {@code false}.
0940 *
0941 * @return {@code true} if the lock was free and was acquired
0942 * by the current thread, or the write lock was already held
0943 * by the current thread; and {@code false} otherwise.
0944 */
0945 public boolean tryLock() {
0946 return sync.tryWriteLock();
0947 }
0948
0949 /**
0950 * Acquires the write lock if it is not held by another thread
0951 * within the given waiting time and the current thread has
0952 * not been {@linkplain Thread#interrupt interrupted}.
0953 *
0954 * <p>Acquires the write lock if neither the read nor write lock
0955 * are held by another thread
0956 * and returns immediately with the value {@code true},
0957 * setting the write lock hold count to one. If this lock has been
0958 * set to use a fair ordering policy then an available lock
0959 * <em>will not</em> be acquired if any other threads are
0960 * waiting for the write lock. This is in contrast to the {@link
0961 * #tryLock()} method. If you want a timed {@code tryLock}
0962 * that does permit barging on a fair lock then combine the
0963 * timed and un-timed forms together:
0964 *
0965 * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
0966 * </pre>
0967 *
0968 * <p>If the current thread already holds this lock then the
0969 * hold count is incremented by one and the method returns
0970 * {@code true}.
0971 *
0972 * <p>If the lock is held by another thread then the current
0973 * thread becomes disabled for thread scheduling purposes and
0974 * lies dormant until one of three things happens:
0975 *
0976 * <ul>
0977 *
0978 * <li>The write lock is acquired by the current thread; or
0979 *
0980 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
0981 * the current thread; or
0982 *
0983 * <li>The specified waiting time elapses
0984 *
0985 * </ul>
0986 *
0987 * <p>If the write lock is acquired then the value {@code true} is
0988 * returned and the write lock hold count is set to one.
0989 *
0990 * <p>If the current thread:
0991 *
0992 * <ul>
0993 *
0994 * <li>has its interrupted status set on entry to this method;
0995 * or
0996 *
0997 * <li>is {@linkplain Thread#interrupt interrupted} while
0998 * acquiring the write lock,
0999 *
1000 * </ul>
1001 *
1002 * then {@link InterruptedException} is thrown and the current
1003 * thread's interrupted status is cleared.
1004 *
1005 * <p>If the specified waiting time elapses then the value
1006 * {@code false} is returned. If the time is less than or
1007 * equal to zero, the method will not wait at all.
1008 *
1009 * <p>In this implementation, as this method is an explicit
1010 * interruption point, preference is given to responding to
1011 * the interrupt over normal or reentrant acquisition of the
1012 * lock, and over reporting the elapse of the waiting time.
1013 *
1014 * @param timeout the time to wait for the write lock
1015 * @param unit the time unit of the timeout argument
1016 *
1017 * @return {@code true} if the lock was free and was acquired
1018 * by the current thread, or the write lock was already held by the
1019 * current thread; and {@code false} if the waiting time
1020 * elapsed before the lock could be acquired.
1021 *
1022 * @throws InterruptedException if the current thread is interrupted
1023 * @throws NullPointerException if the time unit is null
1024 *
1025 */
1026 public boolean tryLock(long timeout, TimeUnit unit)
1027 throws InterruptedException {
1028 return sync.tryAcquireNanos(1, unit.toNanos(timeout));
1029 }
1030
1031 /**
1032 * Attempts to release this lock.
1033 *
1034 * <p>If the current thread is the holder of this lock then
1035 * the hold count is decremented. If the hold count is now
1036 * zero then the lock is released. If the current thread is
1037 * not the holder of this lock then {@link
1038 * IllegalMonitorStateException} is thrown.
1039 *
1040 * @throws IllegalMonitorStateException if the current thread does not
1041 * hold this lock.
1042 */
1043 public void unlock() {
1044 sync.release(1);
1045 }
1046
1047 /**
1048 * Returns a {@link Condition} instance for use with this
1049 * {@link Lock} instance.
1050 * <p>The returned {@link Condition} instance supports the same
1051 * usages as do the {@link Object} monitor methods ({@link
1052 * Object#wait() wait}, {@link Object#notify notify}, and {@link
1053 * Object#notifyAll notifyAll}) when used with the built-in
1054 * monitor lock.
1055 *
1056 * <ul>
1057 *
1058 * <li>If this write lock is not held when any {@link
1059 * Condition} method is called then an {@link
1060 * IllegalMonitorStateException} is thrown. (Read locks are
1061 * held independently of write locks, so are not checked or
1062 * affected. However it is essentially always an error to
1063 * invoke a condition waiting method when the current thread
1064 * has also acquired read locks, since other threads that
1065 * could unblock it will not be able to acquire the write
1066 * lock.)
1067 *
1068 * <li>When the condition {@linkplain Condition#await() waiting}
1069 * methods are called the write lock is released and, before
1070 * they return, the write lock is reacquired and the lock hold
1071 * count restored to what it was when the method was called.
1072 *
1073 * <li>If a thread is {@linkplain Thread#interrupt interrupted} while
1074 * waiting then the wait will terminate, an {@link
1075 * InterruptedException} will be thrown, and the thread's
1076 * interrupted status will be cleared.
1077 *
1078 * <li> Waiting threads are signalled in FIFO order.
1079 *
1080 * <li>The ordering of lock reacquisition for threads returning
1081 * from waiting methods is the same as for threads initially
1082 * acquiring the lock, which is in the default case not specified,
1083 * but for <em>fair</em> locks favors those threads that have been
1084 * waiting the longest.
1085 *
1086 * </ul>
1087 *
1088 * @return the Condition object
1089 */
1090 public Condition newCondition() {
1091 return sync.newCondition();
1092 }
1093
1094 /**
1095 * Returns a string identifying this lock, as well as its lock
1096 * state. The state, in brackets includes either the String
1097 * {@code "Unlocked"} or the String {@code "Locked by"}
1098 * followed by the {@linkplain Thread#getName name} of the owning thread.
1099 *
1100 * @return a string identifying this lock, as well as its lock state
1101 */
1102 public String toString() {
1103 Thread o = sync.getOwner();
1104 return super .toString()
1105 + ((o == null) ? "[Unlocked]"
1106 : "[Locked by thread " + o.getName() + "]");
1107 }
1108
1109 /**
1110 * Queries if this write lock is held by the current thread.
1111 * Identical in effect to {@link
1112 * ReentrantReadWriteLock#isWriteLockedByCurrentThread}.
1113 *
1114 * @return {@code true} if the current thread holds this lock and
1115 * {@code false} otherwise
1116 * @since 1.6
1117 */
1118 public boolean isHeldByCurrentThread() {
1119 return sync.isHeldExclusively();
1120 }
1121
1122 /**
1123 * Queries the number of holds on this write lock by the current
1124 * thread. A thread has a hold on a lock for each lock action
1125 * that is not matched by an unlock action. Identical in effect
1126 * to {@link ReentrantReadWriteLock#getWriteHoldCount}.
1127 *
1128 * @return the number of holds on this lock by the current thread,
1129 * or zero if this lock is not held by the current thread
1130 * @since 1.6
1131 */
1132 public int getHoldCount() {
1133 return sync.getWriteHoldCount();
1134 }
1135 }
1136
1137 // Instrumentation and status
1138
1139 /**
1140 * Returns {@code true} if this lock has fairness set true.
1141 *
1142 * @return {@code true} if this lock has fairness set true
1143 */
1144 public final boolean isFair() {
1145 return sync instanceof FairSync;
1146 }
1147
1148 /**
1149 * Returns the thread that currently owns the write lock, or
1150 * {@code null} if not owned. When this method is called by a
1151 * thread that is not the owner, the return value reflects a
1152 * best-effort approximation of current lock status. For example,
1153 * the owner may be momentarily {@code null} even if there are
1154 * threads trying to acquire the lock but have not yet done so.
1155 * This method is designed to facilitate construction of
1156 * subclasses that provide more extensive lock monitoring
1157 * facilities.
1158 *
1159 * @return the owner, or {@code null} if not owned
1160 */
1161 protected Thread getOwner() {
1162 return sync.getOwner();
1163 }
1164
1165 /**
1166 * Queries the number of read locks held for this lock. This
1167 * method is designed for use in monitoring system state, not for
1168 * synchronization control.
1169 * @return the number of read locks held.
1170 */
1171 public int getReadLockCount() {
1172 return sync.getReadLockCount();
1173 }
1174
1175 /**
1176 * Queries if the write lock is held by any thread. This method is
1177 * designed for use in monitoring system state, not for
1178 * synchronization control.
1179 *
1180 * @return {@code true} if any thread holds the write lock and
1181 * {@code false} otherwise
1182 */
1183 public boolean isWriteLocked() {
1184 return sync.isWriteLocked();
1185 }
1186
1187 /**
1188 * Queries if the write lock is held by the current thread.
1189 *
1190 * @return {@code true} if the current thread holds the write lock and
1191 * {@code false} otherwise
1192 */
1193 public boolean isWriteLockedByCurrentThread() {
1194 return sync.isHeldExclusively();
1195 }
1196
1197 /**
1198 * Queries the number of reentrant write holds on this lock by the
1199 * current thread. A writer thread has a hold on a lock for
1200 * each lock action that is not matched by an unlock action.
1201 *
1202 * @return the number of holds on the write lock by the current thread,
1203 * or zero if the write lock is not held by the current thread
1204 */
1205 public int getWriteHoldCount() {
1206 return sync.getWriteHoldCount();
1207 }
1208
1209 /**
1210 * Queries the number of reentrant read holds on this lock by the
1211 * current thread. A reader thread has a hold on a lock for
1212 * each lock action that is not matched by an unlock action.
1213 *
1214 * @return the number of holds on the read lock by the current thread,
1215 * or zero if the read lock is not held by the current thread
1216 * @since 1.6
1217 */
1218 public int getReadHoldCount() {
1219 return sync.getReadHoldCount();
1220 }
1221
1222 /**
1223 * Returns a collection containing threads that may be waiting to
1224 * acquire the write lock. Because the actual set of threads may
1225 * change dynamically while constructing this result, the returned
1226 * collection is only a best-effort estimate. The elements of the
1227 * returned collection are in no particular order. This method is
1228 * designed to facilitate construction of subclasses that provide
1229 * more extensive lock monitoring facilities.
1230 *
1231 * @return the collection of threads
1232 */
1233 protected Collection<Thread> getQueuedWriterThreads() {
1234 return sync.getExclusiveQueuedThreads();
1235 }
1236
1237 /**
1238 * Returns a collection containing threads that may be waiting to
1239 * acquire the read lock. Because the actual set of threads may
1240 * change dynamically while constructing this result, the returned
1241 * collection is only a best-effort estimate. The elements of the
1242 * returned collection are in no particular order. This method is
1243 * designed to facilitate construction of subclasses that provide
1244 * more extensive lock monitoring facilities.
1245 *
1246 * @return the collection of threads
1247 */
1248 protected Collection<Thread> getQueuedReaderThreads() {
1249 return sync.getSharedQueuedThreads();
1250 }
1251
1252 /**
1253 * Queries whether any threads are waiting to acquire the read or
1254 * write lock. Note that because cancellations may occur at any
1255 * time, a {@code true} return does not guarantee that any other
1256 * thread will ever acquire a lock. This method is designed
1257 * primarily for use in monitoring of the system state.
1258 *
1259 * @return {@code true} if there may be other threads waiting to
1260 * acquire the lock
1261 */
1262 public final boolean hasQueuedThreads() {
1263 return sync.hasQueuedThreads();
1264 }
1265
1266 /**
1267 * Queries whether the given thread is waiting to acquire either
1268 * the read or write lock. Note that because cancellations may
1269 * occur at any time, a {@code true} return does not guarantee
1270 * that this thread will ever acquire a lock. This method is
1271 * designed primarily for use in monitoring of the system state.
1272 *
1273 * @param thread the thread
1274 * @return {@code true} if the given thread is queued waiting for this lock
1275 * @throws NullPointerException if the thread is null
1276 */
1277 public final boolean hasQueuedThread(Thread thread) {
1278 return sync.isQueued(thread);
1279 }
1280
1281 /**
1282 * Returns an estimate of the number of threads waiting to acquire
1283 * either the read or write lock. The value is only an estimate
1284 * because the number of threads may change dynamically while this
1285 * method traverses internal data structures. This method is
1286 * designed for use in monitoring of the system state, not for
1287 * synchronization control.
1288 *
1289 * @return the estimated number of threads waiting for this lock
1290 */
1291 public final int getQueueLength() {
1292 return sync.getQueueLength();
1293 }
1294
1295 /**
1296 * Returns a collection containing threads that may be waiting to
1297 * acquire either the read or write lock. Because the actual set
1298 * of threads may change dynamically while constructing this
1299 * result, the returned collection is only a best-effort estimate.
1300 * The elements of the returned collection are in no particular
1301 * order. This method is designed to facilitate construction of
1302 * subclasses that provide more extensive monitoring facilities.
1303 *
1304 * @return the collection of threads
1305 */
1306 protected Collection<Thread> getQueuedThreads() {
1307 return sync.getQueuedThreads();
1308 }
1309
1310 /**
1311 * Queries whether any threads are waiting on the given condition
1312 * associated with the write lock. Note that because timeouts and
1313 * interrupts may occur at any time, a {@code true} return does
1314 * not guarantee that a future {@code signal} will awaken any
1315 * threads. This method is designed primarily for use in
1316 * monitoring of the system state.
1317 *
1318 * @param condition the condition
1319 * @return {@code true} if there are any waiting threads
1320 * @throws IllegalMonitorStateException if this lock is not held
1321 * @throws IllegalArgumentException if the given condition is
1322 * not associated with this lock
1323 * @throws NullPointerException if the condition is null
1324 */
1325 public boolean hasWaiters(Condition condition) {
1326 if (condition == null)
1327 throw new NullPointerException();
1328 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
1329 throw new IllegalArgumentException("not owner");
1330 return sync
1331 .hasWaiters((AbstractQueuedSynchronizer.ConditionObject) condition);
1332 }
1333
1334 /**
1335 * Returns an estimate of the number of threads waiting on the
1336 * given condition associated with the write lock. Note that because
1337 * timeouts and interrupts may occur at any time, the estimate
1338 * serves only as an upper bound on the actual number of waiters.
1339 * This method is designed for use in monitoring of the system
1340 * state, not for synchronization control.
1341 *
1342 * @param condition the condition
1343 * @return the estimated number of waiting threads
1344 * @throws IllegalMonitorStateException if this lock is not held
1345 * @throws IllegalArgumentException if the given condition is
1346 * not associated with this lock
1347 * @throws NullPointerException if the condition is null
1348 */
1349 public int getWaitQueueLength(Condition condition) {
1350 if (condition == null)
1351 throw new NullPointerException();
1352 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
1353 throw new IllegalArgumentException("not owner");
1354 return sync
1355 .getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject) condition);
1356 }
1357
1358 /**
1359 * Returns a collection containing those threads that may be
1360 * waiting on the given condition associated with the write lock.
1361 * Because the actual set of threads may change dynamically while
1362 * constructing this result, the returned collection is only a
1363 * best-effort estimate. The elements of the returned collection
1364 * are in no particular order. This method is designed to
1365 * facilitate construction of subclasses that provide more
1366 * extensive condition monitoring facilities.
1367 *
1368 * @param condition the condition
1369 * @return the collection of threads
1370 * @throws IllegalMonitorStateException if this lock is not held
1371 * @throws IllegalArgumentException if the given condition is
1372 * not associated with this lock
1373 * @throws NullPointerException if the condition is null
1374 */
1375 protected Collection<Thread> getWaitingThreads(Condition condition) {
1376 if (condition == null)
1377 throw new NullPointerException();
1378 if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
1379 throw new IllegalArgumentException("not owner");
1380 return sync
1381 .getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject) condition);
1382 }
1383
1384 /**
1385 * Returns a string identifying this lock, as well as its lock state.
1386 * The state, in brackets, includes the String {@code "Write locks ="}
1387 * followed by the number of reentrantly held write locks, and the
1388 * String {@code "Read locks ="} followed by the number of held
1389 * read locks.
1390 *
1391 * @return a string identifying this lock, as well as its lock state
1392 */
1393 public String toString() {
1394 int c = sync.getCount();
1395 int w = Sync.exclusiveCount(c);
1396 int r = Sync.sharedCount(c);
1397
1398 return super .toString() + "[Write locks = " + w
1399 + ", Read locks = " + r + "]";
1400 }
1401
1402 }
|