1 *java.util.concurrent.locks.ReentrantReadWriteLock* *ReentrantReadWriteLock* An
3 public class ReentrantReadWriteLock
4 extends |java.lang.Object|
5 implements |java.util.concurrent.locks.ReadWriteLock|
8 |java.util.concurrent.locks.ReentrantReadWriteLock_Description|
9 |java.util.concurrent.locks.ReentrantReadWriteLock_Fields|
10 |java.util.concurrent.locks.ReentrantReadWriteLock_Constructors|
11 |java.util.concurrent.locks.ReentrantReadWriteLock_Methods|
13 ================================================================================
15 *java.util.concurrent.locks.ReentrantReadWriteLock_Constructors*
16 |java.util.concurrent.locks.ReentrantReadWriteLock()|Creates a new ReentrantRea
17 |java.util.concurrent.locks.ReentrantReadWriteLock(boolean)|Creates a new Reent
19 *java.util.concurrent.locks.ReentrantReadWriteLock_Methods*
20 |java.util.concurrent.locks.ReentrantReadWriteLock.getOwner()|Returns the threa
21 |java.util.concurrent.locks.ReentrantReadWriteLock.getQueuedReaderThreads()|Ret
22 |java.util.concurrent.locks.ReentrantReadWriteLock.getQueuedThreads()|Returns a
23 |java.util.concurrent.locks.ReentrantReadWriteLock.getQueuedWriterThreads()|Ret
24 |java.util.concurrent.locks.ReentrantReadWriteLock.getQueueLength()|Returns an
25 |java.util.concurrent.locks.ReentrantReadWriteLock.getReadLockCount()|Queries t
26 |java.util.concurrent.locks.ReentrantReadWriteLock.getWaitingThreads(Condition)|
27 |java.util.concurrent.locks.ReentrantReadWriteLock.getWaitQueueLength(Condition)|
28 |java.util.concurrent.locks.ReentrantReadWriteLock.getWriteHoldCount()|Queries
29 |java.util.concurrent.locks.ReentrantReadWriteLock.hasQueuedThread(Thread)|Quer
30 |java.util.concurrent.locks.ReentrantReadWriteLock.hasQueuedThreads()|Queries w
31 |java.util.concurrent.locks.ReentrantReadWriteLock.hasWaiters(Condition)|Querie
32 |java.util.concurrent.locks.ReentrantReadWriteLock.isFair()|Returns true if thi
33 |java.util.concurrent.locks.ReentrantReadWriteLock.isWriteLocked()|Queries if t
34 |java.util.concurrent.locks.ReentrantReadWriteLock.isWriteLockedByCurrentThread()|
35 |java.util.concurrent.locks.ReentrantReadWriteLock.readLock()|
36 |java.util.concurrent.locks.ReentrantReadWriteLock.toString()|Returns a string
37 |java.util.concurrent.locks.ReentrantReadWriteLock.writeLock()|
39 *java.util.concurrent.locks.ReentrantReadWriteLock_Description*
41 An implementation of (|java.util.concurrent.locks.ReadWriteLock|) supporting
42 similar semantics to (|java.util.concurrent.locks.ReentrantLock|) . This class
43 has the following properties:
47 This class does not impose a reader or writer preference ordering for lock
48 access. However, it does support an optional fairness policy. When constructed
49 as fair, threads contend for entry using an approximately arrival-order policy.
50 When the write lock is released either the longest-waiting single writer will
51 be assigned the write lock, or if there is a reader waiting longer than any
52 writer, the set of readers will be assigned the read lock. When constructed as
53 non-fair, the order of entry to the lock need not be in arrival order. In
54 either case, if readers are active and a writer enters the lock then no
55 subsequent readers will be granted the read lock until after that writer has
56 acquired and released the write lock.
58 Reentrancy This lock allows both readers and writers to reacquire read or write
59 locks in the style of a (|java.util.concurrent.locks.ReentrantLock|) . Readers
60 are not allowed until all write locks held by the writing thread have been
61 released. Additionally, a writer can acquire the read lock - but not
62 vice-versa. Among other applications, reentrancy can be useful when write locks
63 are held during calls or callbacks to methods that perform reads under read
64 locks. If a reader tries to acquire the write lock it will never succeed.
66 Lock downgrading Reentrancy also allows downgrading from the write lock to a
67 read lock, by acquiring the write lock, then the read lock and then releasing
68 the write lock. However, upgrading from a read lock to the write lock is not
71 Interruption of lock acquisition The read lock and write lock both support
72 interruption during lock acquisition.
74 (|java.util.concurrent.locks.Condition|) support The write lock provides a
75 (|java.util.concurrent.locks.Condition|) implementation that behaves in the
76 same way, with respect to the write lock, as the
77 (|java.util.concurrent.locks.Condition|) implementation provided by
78 (|java.util.concurrent.locks.ReentrantLock|) does for
79 (|java.util.concurrent.locks.ReentrantLock|) . This
80 (|java.util.concurrent.locks.Condition|) can, of course, only be used with the
81 write lock. The read lock does not support a
82 (|java.util.concurrent.locks.Condition|) and readLock().newCondition() throws
83 UnsupportedOperationException.
85 Instrumentation This class supports methods to determine whether locks are held
86 or contended. These methods are designed for monitoring system state, not for
87 synchronization control.
89 Serialization of this class behaves in the same way as built-in locks: a
90 deserialized lock is in the unlocked state, regardless of its state when
93 Sample usages. Here is a code sketch showing how to exploit reentrancy to
94 perform lock downgrading after updating a cache (exception handling is elided
97 class CachedData { Object data; volatile boolean cacheValid;
98 ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
100 void processCachedData() { rwl.readLock().lock(); if (!cacheValid) { // upgrade
101 lock manually rwl.readLock().unlock(); // must unlock first to obtain writelock
102 rwl.writeLock().lock(); if (!cacheValid) { // recheck data = ... cacheValid =
103 true; } // downgrade lock rwl.readLock().lock(); // reacquire read without
104 giving up write lock rwl.writeLock().unlock(); // unlock write, still hold read
107 use(data); rwl.readLock().unlock(); } }
109 ReentrantReadWriteLocks can be used to improve concurrency in some uses of some
110 kinds of Collections. This is typically worthwhile only when the collections
111 are expected to be large, accessed by more reader threads than writer threads,
112 and entail operations with overhead that outweighs synchronization overhead.
113 For example, here is a class using a TreeMap that is expected to be large and
114 concurrently accessed.
118 class RWDictionary { private final Map<String, Data> m = new TreeMap<String,
119 Data>(); private final ReentrantReadWriteLock rwl = new
120 ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); private final
121 Lock w = rwl.writeLock();
123 public Data get(String key) { r.lock(); try { return m.get(key); } finally {
124 r.unlock(); } } public String[] allKeys() { r.lock(); try { return
125 m.keySet().toArray(); } finally { r.unlock(); } } public Data put(String key,
126 Data value) { w.lock(); try { return m.put(key, value); } finally { w.unlock();
127 } } public void clear() { w.lock(); try { m.clear(); } finally { w.unlock(); }
134 A reentrant write lock intrinsically defines an owner and can only be released
135 by the thread that acquired it. In contrast, in this implementation, the read
136 lock has no concept of ownership, and there is no requirement that the thread
137 releasing a read lock is the same as the one that acquired it. However, this
138 property is not guaranteed to hold in future implementations of this class.
140 This lock supports a maximum of 65536 recursive write locks and 65536 read
141 locks. Attempts to exceed these limits result in (|java.lang.Error|) throws
142 from locking methods.
145 *java.util.concurrent.locks.ReentrantReadWriteLock()*
147 public ReentrantReadWriteLock()
149 Creates a new ReentrantReadWriteLock with default ordering properties.
152 *java.util.concurrent.locks.ReentrantReadWriteLock(boolean)*
154 public ReentrantReadWriteLock(boolean fair)
156 Creates a new ReentrantReadWriteLock with the given fairness policy.
158 fair - true if this lock should use a fair ordering policy
160 *java.util.concurrent.locks.ReentrantReadWriteLock.getOwner()*
162 protected |java.lang.Thread| getOwner()
164 Returns the thread that currently owns the write lock, or null if not owned.
165 Note that the owner may be momentarily null even if there are threads trying to
166 acquire the lock but have not yet done so. This method is designed to
167 facilitate construction of subclasses that provide more extensive lock
168 monitoring facilities.
171 Returns: the owner, or null if not owned.
172 *java.util.concurrent.locks.ReentrantReadWriteLock.getQueuedReaderThreads()*
174 protected |java.util.Collection| getQueuedReaderThreads()
176 Returns a collection containing threads that may be waiting to acquire the read
177 lock. Because the actual set of threads may change dynamically while
178 constructing this result, the returned collection is only a best-effort
179 estimate. The elements of the returned collection are in no particular order.
180 This method is designed to facilitate construction of subclasses that provide
181 more extensive lock monitoring facilities.
184 Returns: the collection of threads
185 *java.util.concurrent.locks.ReentrantReadWriteLock.getQueuedThreads()*
187 protected |java.util.Collection| getQueuedThreads()
189 Returns a collection containing threads that may be waiting to acquire either
190 the read or write lock. Because the actual set of threads may change
191 dynamically while constructing this result, the returned collection is only a
192 best-effort estimate. The elements of the returned collection are in no
193 particular order. This method is designed to facilitate construction of
194 subclasses that provide more extensive monitoring facilities.
197 Returns: the collection of threads
198 *java.util.concurrent.locks.ReentrantReadWriteLock.getQueuedWriterThreads()*
200 protected |java.util.Collection| getQueuedWriterThreads()
202 Returns a collection containing threads that may be waiting to acquire the
203 write lock. Because the actual set of threads may change dynamically while
204 constructing this result, the returned collection is only a best-effort
205 estimate. The elements of the returned collection are in no particular order.
206 This method is designed to facilitate construction of subclasses that provide
207 more extensive lock monitoring facilities.
210 Returns: the collection of threads
211 *java.util.concurrent.locks.ReentrantReadWriteLock.getQueueLength()*
213 public final int getQueueLength()
215 Returns an estimate of the number of threads waiting to acquire either the read
216 or write lock. The value is only an estimate because the number of threads may
217 change dynamically while this method traverses internal data structures. This
218 method is designed for use in monitoring of the system state, not for
219 synchronization control.
222 Returns: the estimated number of threads waiting for this lock
223 *java.util.concurrent.locks.ReentrantReadWriteLock.getReadLockCount()*
225 public int getReadLockCount()
227 Queries the number of read locks held for this lock. This method is designed
228 for use in monitoring system state, not for synchronization control.
231 Returns: the number of read locks held.
232 *java.util.concurrent.locks.ReentrantReadWriteLock.getWaitingThreads(Condition)*
234 protected |java.util.Collection| getWaitingThreads(java.util.concurrent.locks.Condition condition)
236 Returns a collection containing those threads that may be waiting on the given
237 condition associated with the write lock. Because the actual set of threads may
238 change dynamically while constructing this result, the returned collection is
239 only a best-effort estimate. The elements of the returned collection are in no
240 particular order. This method is designed to facilitate construction of
241 subclasses that provide more extensive condition monitoring facilities.
243 condition - the condition
245 Returns: the collection of threads
246 *java.util.concurrent.locks.ReentrantReadWriteLock.getWaitQueueLength(Condition)*
248 public int getWaitQueueLength(java.util.concurrent.locks.Condition condition)
250 Returns an estimate of the number of threads waiting on the given condition
251 associated with the write lock. Note that because timeouts and interrupts may
252 occur at any time, the estimate serves only as an upper bound on the actual
253 number of waiters. This method is designed for use in monitoring of the system
254 state, not for synchronization control.
256 condition - the condition
258 Returns: the estimated number of waiting threads.
259 *java.util.concurrent.locks.ReentrantReadWriteLock.getWriteHoldCount()*
261 public int getWriteHoldCount()
263 Queries the number of reentrant write holds on this lock by the current thread.
264 A writer thread has a hold on a lock for each lock action that is not matched
268 Returns: the number of holds on the write lock by the current thread, or zero if the
269 write lock is not held by the current thread.
270 *java.util.concurrent.locks.ReentrantReadWriteLock.hasQueuedThread(Thread)*
272 public final boolean hasQueuedThread(java.lang.Thread thread)
274 Queries whether the given thread is waiting to acquire either the read or write
275 lock. Note that because cancellations may occur at any time, a true return does
276 not guarantee that this thread will ever acquire a lock. This method is
277 designed primarily for use in monitoring of the system state.
281 Returns: true if the given thread is queued waiting for this lock.
282 *java.util.concurrent.locks.ReentrantReadWriteLock.hasQueuedThreads()*
284 public final boolean hasQueuedThreads()
286 Queries whether any threads are waiting to acquire the read or write lock. Note
287 that because cancellations may occur at any time, a true return does not
288 guarantee that any other thread will ever acquire a lock. This method is
289 designed primarily for use in monitoring of the system state.
292 Returns: true if there may be other threads waiting to acquire the lock.
293 *java.util.concurrent.locks.ReentrantReadWriteLock.hasWaiters(Condition)*
295 public boolean hasWaiters(java.util.concurrent.locks.Condition condition)
297 Queries whether any threads are waiting on the given condition associated with
298 the write lock. Note that because timeouts and interrupts may occur at any
299 time, a true return does not guarantee that a future signal will awaken any
300 threads. This method is designed primarily for use in monitoring of the system
303 condition - the condition
305 Returns: true if there are any waiting threads.
306 *java.util.concurrent.locks.ReentrantReadWriteLock.isFair()*
308 public final boolean isFair()
310 Returns true if this lock has fairness set true.
313 Returns: true if this lock has fairness set true.
314 *java.util.concurrent.locks.ReentrantReadWriteLock.isWriteLocked()*
316 public boolean isWriteLocked()
318 Queries if the write lock is held by any thread. This method is designed for
319 use in monitoring system state, not for synchronization control.
322 Returns: true if any thread holds the write lock and false otherwise.
323 *java.util.concurrent.locks.ReentrantReadWriteLock.isWriteLockedByCurrentThread()*
325 public boolean isWriteLockedByCurrentThread()
327 Queries if the write lock is held by the current thread.
330 Returns: true if the current thread holds the write lock and false otherwise.
331 *java.util.concurrent.locks.ReentrantReadWriteLock.readLock()*
333 public |java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock| readLock()
338 *java.util.concurrent.locks.ReentrantReadWriteLock.toString()*
340 public |java.lang.String| toString()
342 Returns a string identifying this lock, as well as its lock state. The state,
343 in brackets, includes the String Write locks = followed by the number of
344 reentrantly held write locks, and the String Read locks = followed by the
345 number of held read locks.
348 Returns: a string identifying this lock, as well as its lock state.
349 *java.util.concurrent.locks.ReentrantReadWriteLock.writeLock()*
351 public |java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock| writeLock()