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