ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/StampedLockTest.java
(Generate patch)

Comparing jsr166/src/test/tck/StampedLockTest.java (file contents):
Revision 1.3 by jsr166, Sat Feb 9 19:33:08 2013 UTC vs.
Revision 1.47 by dl, Tue Jan 26 13:33:06 2021 UTC

# Line 3 | Line 3
3   * with assistance from members of JCP JSR-166 Expert Group and
4   * released to the public domain, as explained at
5   * http://creativecommons.org/publicdomain/zero/1.0/
6 * Other contributors include Andrew Wright, Jeffrey Hayes,
7 * Pat Fisher, Mike Judd.
6   */
7  
8 < import junit.framework.*;
8 > import static java.util.concurrent.TimeUnit.DAYS;
9 > import static java.util.concurrent.TimeUnit.MILLISECONDS;
10 >
11 > import static java.util.concurrent.locks.StampedLock.isLockStamp;
12 > import static java.util.concurrent.locks.StampedLock.isOptimisticReadStamp;
13 > import static java.util.concurrent.locks.StampedLock.isReadLockStamp;
14 > import static java.util.concurrent.locks.StampedLock.isWriteLockStamp;
15 >
16 > import java.util.ArrayList;
17 > import java.util.List;
18 > import java.util.concurrent.Callable;
19 > import java.util.concurrent.CompletableFuture;
20 > import java.util.concurrent.CountDownLatch;
21 > import java.util.concurrent.Future;
22 > import java.util.concurrent.ThreadLocalRandom;
23 > import java.util.concurrent.TimeUnit;
24   import java.util.concurrent.atomic.AtomicBoolean;
12 import java.util.concurrent.locks.Condition;
25   import java.util.concurrent.locks.Lock;
14 import java.util.concurrent.locks.ReadWriteLock;
26   import java.util.concurrent.locks.StampedLock;
27 < import java.util.concurrent.CountDownLatch;
28 < import static java.util.concurrent.TimeUnit.MILLISECONDS;
29 < import java.util.*;
27 > import java.util.function.BiConsumer;
28 > import java.util.function.Consumer;
29 > import java.util.function.Function;
30 >
31 > import junit.framework.Test;
32 > import junit.framework.TestSuite;
33  
34   public class StampedLockTest extends JSR166TestCase {
35      public static void main(String[] args) {
36 <        junit.textui.TestRunner.run(suite());
36 >        main(suite(), args);
37      }
38      public static Test suite() {
39          return new TestSuite(StampedLockTest.class);
40      }
41  
42 <    // XXXX Just a skeleton implementation for now.
43 <    public void testTODO() {
44 <        fail("Please add some real tests!");
45 <    }
46 <
47 <    public void testConstructor() { new StampedLock(); }
48 <
49 < //     /**
50 < //      * A runnable calling lockInterruptibly
51 < //      */
52 < //     class InterruptibleLockRunnable extends CheckedRunnable {
53 < //         final ReentrantReadWriteLock lock;
54 < //         InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
55 < //         public void realRun() throws InterruptedException {
56 < //             lock.writeLock().lockInterruptibly();
57 < //         }
58 < //     }
59 <
60 < //     /**
61 < //      * A runnable calling lockInterruptibly that expects to be
62 < //      * interrupted
63 < //      */
64 < //     class InterruptedLockRunnable extends CheckedInterruptedRunnable {
65 < //         final ReentrantReadWriteLock lock;
66 < //         InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
67 < //         public void realRun() throws InterruptedException {
68 < //             lock.writeLock().lockInterruptibly();
69 < //         }
70 < //     }
71 <
72 < //     /**
73 < //      * Subclass to expose protected methods
74 < //      */
75 < //     static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
76 < //         PublicReentrantReadWriteLock() { super(); }
77 < //         PublicReentrantReadWriteLock(boolean fair) { super(fair); }
78 < //         public Thread getOwner() {
79 < //             return super.getOwner();
80 < //         }
81 < //         public Collection<Thread> getQueuedThreads() {
82 < //             return super.getQueuedThreads();
83 < //         }
84 < //         public Collection<Thread> getWaitingThreads(Condition c) {
85 < //             return super.getWaitingThreads(c);
86 < //         }
87 < //     }
88 <
89 < //     /**
90 < //      * Releases write lock, checking that it had a hold count of 1.
91 < //      */
92 < //     void releaseWriteLock(PublicReentrantReadWriteLock lock) {
93 < //         ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
94 < //         assertWriteLockedByMoi(lock);
95 < //         assertEquals(1, lock.getWriteHoldCount());
96 < //         writeLock.unlock();
97 < //         assertNotWriteLocked(lock);
98 < //     }
99 <
100 < //     /**
101 < //      * Spin-waits until lock.hasQueuedThread(t) becomes true.
102 < //      */
103 < //     void waitForQueuedThread(PublicReentrantReadWriteLock lock, Thread t) {
104 < //         long startTime = System.nanoTime();
105 < //         while (!lock.hasQueuedThread(t)) {
106 < //             if (millisElapsedSince(startTime) > LONG_DELAY_MS)
107 < //                 throw new AssertionFailedError("timed out");
108 < //             Thread.yield();
109 < //         }
110 < //         assertTrue(t.isAlive());
111 < //         assertTrue(lock.getOwner() != t);
112 < //     }
113 <
114 < //     /**
115 < //      * Checks that lock is not write-locked.
116 < //      */
117 < //     void assertNotWriteLocked(PublicReentrantReadWriteLock lock) {
118 < //         assertFalse(lock.isWriteLocked());
119 < //         assertFalse(lock.isWriteLockedByCurrentThread());
120 < //         assertFalse(lock.writeLock().isHeldByCurrentThread());
121 < //         assertEquals(0, lock.getWriteHoldCount());
122 < //         assertEquals(0, lock.writeLock().getHoldCount());
123 < //         assertNull(lock.getOwner());
124 < //     }
125 <
126 < //     /**
127 < //      * Checks that lock is write-locked by the given thread.
128 < //      */
129 < //     void assertWriteLockedBy(PublicReentrantReadWriteLock lock, Thread t) {
130 < //         assertTrue(lock.isWriteLocked());
131 < //         assertSame(t, lock.getOwner());
132 < //         assertEquals(t == Thread.currentThread(),
133 < //                      lock.isWriteLockedByCurrentThread());
134 < //         assertEquals(t == Thread.currentThread(),
135 < //                      lock.writeLock().isHeldByCurrentThread());
136 < //         assertEquals(t == Thread.currentThread(),
137 < //                      lock.getWriteHoldCount() > 0);
138 < //         assertEquals(t == Thread.currentThread(),
139 < //                      lock.writeLock().getHoldCount() > 0);
140 < //         assertEquals(0, lock.getReadLockCount());
141 < //     }
142 <
143 < //     /**
144 < //      * Checks that lock is write-locked by the current thread.
145 < //      */
146 < //     void assertWriteLockedByMoi(PublicReentrantReadWriteLock lock) {
147 < //         assertWriteLockedBy(lock, Thread.currentThread());
148 < //     }
149 <
150 < //     /**
151 < //      * Checks that condition c has no waiters.
152 < //      */
153 < //     void assertHasNoWaiters(PublicReentrantReadWriteLock lock, Condition c) {
154 < //         assertHasWaiters(lock, c, new Thread[] {});
155 < //     }
156 <
157 < //     /**
158 < //      * Checks that condition c has exactly the given waiter threads.
159 < //      */
160 < //     void assertHasWaiters(PublicReentrantReadWriteLock lock, Condition c,
161 < //                           Thread... threads) {
162 < //         lock.writeLock().lock();
163 < //         assertEquals(threads.length > 0, lock.hasWaiters(c));
164 < //         assertEquals(threads.length, lock.getWaitQueueLength(c));
165 < //         assertEquals(threads.length == 0, lock.getWaitingThreads(c).isEmpty());
166 < //         assertEquals(threads.length, lock.getWaitingThreads(c).size());
167 < //         assertEquals(new HashSet<Thread>(lock.getWaitingThreads(c)),
168 < //                      new HashSet<Thread>(Arrays.asList(threads)));
169 < //         lock.writeLock().unlock();
170 < //     }
171 <
172 < //     enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil };
173 <
174 < //     /**
175 < //      * Awaits condition using the specified AwaitMethod.
176 < //      */
177 < //     void await(Condition c, AwaitMethod awaitMethod)
178 < //             throws InterruptedException {
179 < //         switch (awaitMethod) {
180 < //         case await:
181 < //             c.await();
182 < //             break;
183 < //         case awaitTimed:
184 < //             assertTrue(c.await(2 * LONG_DELAY_MS, MILLISECONDS));
185 < //             break;
186 < //         case awaitNanos:
187 < //             long nanosRemaining = c.awaitNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
188 < //             assertTrue(nanosRemaining > 0);
189 < //             break;
190 < //         case awaitUntil:
191 < //             java.util.Date d = new java.util.Date();
192 < //             assertTrue(c.awaitUntil(new java.util.Date(d.getTime() + 2 * LONG_DELAY_MS)));
193 < //             break;
194 < //         }
195 < //     }
196 <
197 < //     /**
198 < //      * Constructor sets given fairness, and is in unlocked state
199 < //      */
200 < //     public void testConstructor() {
201 < //         PublicReentrantReadWriteLock lock;
202 <
203 < //         lock = new PublicReentrantReadWriteLock();
204 < //         assertFalse(lock.isFair());
205 < //         assertNotWriteLocked(lock);
206 < //         assertEquals(0, lock.getReadLockCount());
207 <
208 < //         lock = new PublicReentrantReadWriteLock(true);
209 < //         assertTrue(lock.isFair());
210 < //         assertNotWriteLocked(lock);
211 < //         assertEquals(0, lock.getReadLockCount());
212 <
213 < //         lock = new PublicReentrantReadWriteLock(false);
214 < //         assertFalse(lock.isFair());
215 < //         assertNotWriteLocked(lock);
216 < //         assertEquals(0, lock.getReadLockCount());
217 < //     }
218 <
219 < //     /**
220 < //      * write-locking and read-locking an unlocked lock succeed
221 < //      */
222 < //     public void testLock()      { testLock(false); }
223 < //     public void testLock_fair() { testLock(true); }
224 < //     public void testLock(boolean fair) {
225 < //         PublicReentrantReadWriteLock lock =
226 < //             new PublicReentrantReadWriteLock(fair);
227 < //         assertNotWriteLocked(lock);
228 < //         lock.writeLock().lock();
229 < //         assertWriteLockedByMoi(lock);
230 < //         lock.writeLock().unlock();
231 < //         assertNotWriteLocked(lock);
232 < //         assertEquals(0, lock.getReadLockCount());
233 < //         lock.readLock().lock();
234 < //         assertNotWriteLocked(lock);
235 < //         assertEquals(1, lock.getReadLockCount());
236 < //         lock.readLock().unlock();
237 < //         assertNotWriteLocked(lock);
238 < //         assertEquals(0, lock.getReadLockCount());
239 < //     }
240 <
241 < //     /**
242 < //      * getWriteHoldCount returns number of recursive holds
243 < //      */
244 < //     public void testGetWriteHoldCount()      { testGetWriteHoldCount(false); }
245 < //     public void testGetWriteHoldCount_fair() { testGetWriteHoldCount(true); }
246 < //     public void testGetWriteHoldCount(boolean fair) {
247 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
248 < //         for (int i = 1; i <= SIZE; i++) {
249 < //             lock.writeLock().lock();
250 < //             assertEquals(i,lock.getWriteHoldCount());
251 < //         }
252 < //         for (int i = SIZE; i > 0; i--) {
253 < //             lock.writeLock().unlock();
254 < //             assertEquals(i-1,lock.getWriteHoldCount());
255 < //         }
256 < //     }
257 <
258 < //     /**
259 < //      * writelock.getHoldCount returns number of recursive holds
260 < //      */
261 < //     public void testGetHoldCount()      { testGetHoldCount(false); }
262 < //     public void testGetHoldCount_fair() { testGetHoldCount(true); }
263 < //     public void testGetHoldCount(boolean fair) {
264 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
265 < //         for (int i = 1; i <= SIZE; i++) {
266 < //             lock.writeLock().lock();
267 < //             assertEquals(i,lock.writeLock().getHoldCount());
268 < //         }
269 < //         for (int i = SIZE; i > 0; i--) {
270 < //             lock.writeLock().unlock();
271 < //             assertEquals(i-1,lock.writeLock().getHoldCount());
272 < //         }
273 < //     }
274 <
275 < //     /**
276 < //      * getReadHoldCount returns number of recursive holds
277 < //      */
278 < //     public void testGetReadHoldCount()      { testGetReadHoldCount(false); }
279 < //     public void testGetReadHoldCount_fair() { testGetReadHoldCount(true); }
280 < //     public void testGetReadHoldCount(boolean fair) {
281 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
282 < //         for (int i = 1; i <= SIZE; i++) {
283 < //             lock.readLock().lock();
284 < //             assertEquals(i,lock.getReadHoldCount());
285 < //         }
286 < //         for (int i = SIZE; i > 0; i--) {
287 < //             lock.readLock().unlock();
288 < //             assertEquals(i-1,lock.getReadHoldCount());
289 < //         }
290 < //     }
291 <
292 < //     /**
293 < //      * write-unlocking an unlocked lock throws IllegalMonitorStateException
294 < //      */
295 < //     public void testWriteUnlock_IMSE()      { testWriteUnlock_IMSE(false); }
296 < //     public void testWriteUnlock_IMSE_fair() { testWriteUnlock_IMSE(true); }
297 < //     public void testWriteUnlock_IMSE(boolean fair) {
298 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
299 < //         try {
300 < //             lock.writeLock().unlock();
301 < //             shouldThrow();
302 < //         } catch (IllegalMonitorStateException success) {}
303 < //     }
304 <
305 < //     /**
306 < //      * read-unlocking an unlocked lock throws IllegalMonitorStateException
307 < //      */
308 < //     public void testReadUnlock_IMSE()      { testReadUnlock_IMSE(false); }
309 < //     public void testReadUnlock_IMSE_fair() { testReadUnlock_IMSE(true); }
310 < //     public void testReadUnlock_IMSE(boolean fair) {
311 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
312 < //         try {
313 < //             lock.readLock().unlock();
314 < //             shouldThrow();
315 < //         } catch (IllegalMonitorStateException success) {}
316 < //     }
317 <
318 < //     /**
319 < //      * write-lockInterruptibly is interruptible
320 < //      */
321 < //     public void testWriteLockInterruptibly_Interruptible()      { testWriteLockInterruptibly_Interruptible(false); }
322 < //     public void testWriteLockInterruptibly_Interruptible_fair() { testWriteLockInterruptibly_Interruptible(true); }
323 < //     public void testWriteLockInterruptibly_Interruptible(boolean fair) {
324 < //         final PublicReentrantReadWriteLock lock =
325 < //             new PublicReentrantReadWriteLock(fair);
326 < //         lock.writeLock().lock();
327 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
328 < //             public void realRun() throws InterruptedException {
329 < //                 lock.writeLock().lockInterruptibly();
330 < //             }});
331 <
332 < //         waitForQueuedThread(lock, t);
333 < //         t.interrupt();
334 < //         awaitTermination(t);
335 < //         releaseWriteLock(lock);
336 < //     }
337 <
338 < //     /**
339 < //      * timed write-tryLock is interruptible
340 < //      */
341 < //     public void testWriteTryLock_Interruptible()      { testWriteTryLock_Interruptible(false); }
342 < //     public void testWriteTryLock_Interruptible_fair() { testWriteTryLock_Interruptible(true); }
343 < //     public void testWriteTryLock_Interruptible(boolean fair) {
344 < //         final PublicReentrantReadWriteLock lock =
345 < //             new PublicReentrantReadWriteLock(fair);
346 < //         lock.writeLock().lock();
347 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
348 < //             public void realRun() throws InterruptedException {
349 < //                 lock.writeLock().tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
350 < //             }});
351 <
352 < //         waitForQueuedThread(lock, t);
353 < //         t.interrupt();
354 < //         awaitTermination(t);
355 < //         releaseWriteLock(lock);
356 < //     }
357 <
358 < //     /**
359 < //      * read-lockInterruptibly is interruptible
360 < //      */
361 < //     public void testReadLockInterruptibly_Interruptible()      { testReadLockInterruptibly_Interruptible(false); }
362 < //     public void testReadLockInterruptibly_Interruptible_fair() { testReadLockInterruptibly_Interruptible(true); }
363 < //     public void testReadLockInterruptibly_Interruptible(boolean fair) {
364 < //         final PublicReentrantReadWriteLock lock =
365 < //             new PublicReentrantReadWriteLock(fair);
366 < //         lock.writeLock().lock();
367 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
368 < //             public void realRun() throws InterruptedException {
369 < //                 lock.readLock().lockInterruptibly();
370 < //             }});
371 <
372 < //         waitForQueuedThread(lock, t);
373 < //         t.interrupt();
374 < //         awaitTermination(t);
375 < //         releaseWriteLock(lock);
376 < //     }
377 <
378 < //     /**
379 < //      * timed read-tryLock is interruptible
380 < //      */
381 < //     public void testReadTryLock_Interruptible()      { testReadTryLock_Interruptible(false); }
382 < //     public void testReadTryLock_Interruptible_fair() { testReadTryLock_Interruptible(true); }
383 < //     public void testReadTryLock_Interruptible(boolean fair) {
384 < //         final PublicReentrantReadWriteLock lock =
385 < //             new PublicReentrantReadWriteLock(fair);
386 < //         lock.writeLock().lock();
387 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
388 < //             public void realRun() throws InterruptedException {
389 < //                 lock.readLock().tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
390 < //             }});
391 <
392 < //         waitForQueuedThread(lock, t);
393 < //         t.interrupt();
394 < //         awaitTermination(t);
395 < //         releaseWriteLock(lock);
396 < //     }
397 <
398 < //     /**
399 < //      * write-tryLock on an unlocked lock succeeds
400 < //      */
401 < //     public void testWriteTryLock()      { testWriteTryLock(false); }
402 < //     public void testWriteTryLock_fair() { testWriteTryLock(true); }
403 < //     public void testWriteTryLock(boolean fair) {
404 < //         final PublicReentrantReadWriteLock lock =
405 < //             new PublicReentrantReadWriteLock(fair);
406 < //         assertTrue(lock.writeLock().tryLock());
407 < //         assertWriteLockedByMoi(lock);
408 < //         assertTrue(lock.writeLock().tryLock());
409 < //         assertWriteLockedByMoi(lock);
410 < //         lock.writeLock().unlock();
411 < //         releaseWriteLock(lock);
412 < //     }
413 <
414 < //     /**
415 < //      * write-tryLock fails if locked
416 < //      */
417 < //     public void testWriteTryLockWhenLocked()      { testWriteTryLockWhenLocked(false); }
418 < //     public void testWriteTryLockWhenLocked_fair() { testWriteTryLockWhenLocked(true); }
419 < //     public void testWriteTryLockWhenLocked(boolean fair) {
420 < //         final PublicReentrantReadWriteLock lock =
421 < //             new PublicReentrantReadWriteLock(fair);
422 < //         lock.writeLock().lock();
423 < //         Thread t = newStartedThread(new CheckedRunnable() {
424 < //             public void realRun() {
425 < //                 assertFalse(lock.writeLock().tryLock());
426 < //             }});
427 <
428 < //         awaitTermination(t);
429 < //         releaseWriteLock(lock);
430 < //     }
431 <
432 < //     /**
433 < //      * read-tryLock fails if locked
434 < //      */
435 < //     public void testReadTryLockWhenLocked()      { testReadTryLockWhenLocked(false); }
436 < //     public void testReadTryLockWhenLocked_fair() { testReadTryLockWhenLocked(true); }
437 < //     public void testReadTryLockWhenLocked(boolean fair) {
438 < //         final PublicReentrantReadWriteLock lock =
439 < //             new PublicReentrantReadWriteLock(fair);
440 < //         lock.writeLock().lock();
441 < //         Thread t = newStartedThread(new CheckedRunnable() {
442 < //             public void realRun() {
443 < //                 assertFalse(lock.readLock().tryLock());
444 < //             }});
445 <
446 < //         awaitTermination(t);
447 < //         releaseWriteLock(lock);
448 < //     }
449 <
450 < //     /**
451 < //      * Multiple threads can hold a read lock when not write-locked
452 < //      */
453 < //     public void testMultipleReadLocks()      { testMultipleReadLocks(false); }
454 < //     public void testMultipleReadLocks_fair() { testMultipleReadLocks(true); }
455 < //     public void testMultipleReadLocks(boolean fair) {
456 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
457 < //         lock.readLock().lock();
458 < //         Thread t = newStartedThread(new CheckedRunnable() {
459 < //             public void realRun() throws InterruptedException {
460 < //                 assertTrue(lock.readLock().tryLock());
461 < //                 lock.readLock().unlock();
462 < //                 assertTrue(lock.readLock().tryLock(LONG_DELAY_MS, MILLISECONDS));
463 < //                 lock.readLock().unlock();
464 < //                 lock.readLock().lock();
465 < //                 lock.readLock().unlock();
466 < //             }});
467 <
468 < //         awaitTermination(t);
469 < //         lock.readLock().unlock();
470 < //     }
471 <
472 < //     /**
473 < //      * A writelock succeeds only after a reading thread unlocks
474 < //      */
475 < //     public void testWriteAfterReadLock()      { testWriteAfterReadLock(false); }
476 < //     public void testWriteAfterReadLock_fair() { testWriteAfterReadLock(true); }
477 < //     public void testWriteAfterReadLock(boolean fair) {
478 < //         final PublicReentrantReadWriteLock lock =
479 < //             new PublicReentrantReadWriteLock(fair);
480 < //         lock.readLock().lock();
481 < //         Thread t = newStartedThread(new CheckedRunnable() {
482 < //             public void realRun() {
483 < //                 assertEquals(1, lock.getReadLockCount());
484 < //                 lock.writeLock().lock();
485 < //                 assertEquals(0, lock.getReadLockCount());
486 < //                 lock.writeLock().unlock();
487 < //             }});
488 < //         waitForQueuedThread(lock, t);
489 < //         assertNotWriteLocked(lock);
490 < //         assertEquals(1, lock.getReadLockCount());
491 < //         lock.readLock().unlock();
492 < //         assertEquals(0, lock.getReadLockCount());
493 < //         awaitTermination(t);
494 < //         assertNotWriteLocked(lock);
495 < //     }
496 <
497 < //     /**
498 < //      * A writelock succeeds only after reading threads unlock
499 < //      */
500 < //     public void testWriteAfterMultipleReadLocks()      { testWriteAfterMultipleReadLocks(false); }
501 < //     public void testWriteAfterMultipleReadLocks_fair() { testWriteAfterMultipleReadLocks(true); }
502 < //     public void testWriteAfterMultipleReadLocks(boolean fair) {
503 < //         final PublicReentrantReadWriteLock lock =
504 < //             new PublicReentrantReadWriteLock(fair);
505 < //         lock.readLock().lock();
506 < //         lock.readLock().lock();
507 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
508 < //             public void realRun() {
509 < //                 lock.readLock().lock();
510 < //                 assertEquals(3, lock.getReadLockCount());
511 < //                 lock.readLock().unlock();
512 < //             }});
513 < //         awaitTermination(t1);
514 <
515 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
516 < //             public void realRun() {
517 < //                 assertEquals(2, lock.getReadLockCount());
518 < //                 lock.writeLock().lock();
519 < //                 assertEquals(0, lock.getReadLockCount());
520 < //                 lock.writeLock().unlock();
521 < //             }});
522 < //         waitForQueuedThread(lock, t2);
523 < //         assertNotWriteLocked(lock);
524 < //         assertEquals(2, lock.getReadLockCount());
525 < //         lock.readLock().unlock();
526 < //         lock.readLock().unlock();
527 < //         assertEquals(0, lock.getReadLockCount());
528 < //         awaitTermination(t2);
529 < //         assertNotWriteLocked(lock);
530 < //     }
531 <
532 < //     /**
533 < //      * A thread that tries to acquire a fair read lock (non-reentrantly)
534 < //      * will block if there is a waiting writer thread
535 < //      */
536 < //     public void testReaderWriterReaderFairFifo() {
537 < //         final PublicReentrantReadWriteLock lock =
538 < //             new PublicReentrantReadWriteLock(true);
539 < //         final AtomicBoolean t1GotLock = new AtomicBoolean(false);
540 <
541 < //         lock.readLock().lock();
542 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
543 < //             public void realRun() {
544 < //                 assertEquals(1, lock.getReadLockCount());
545 < //                 lock.writeLock().lock();
546 < //                 assertEquals(0, lock.getReadLockCount());
547 < //                 t1GotLock.set(true);
548 < //                 lock.writeLock().unlock();
549 < //             }});
550 < //         waitForQueuedThread(lock, t1);
551 <
552 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
553 < //             public void realRun() {
554 < //                 assertEquals(1, lock.getReadLockCount());
555 < //                 lock.readLock().lock();
556 < //                 assertEquals(1, lock.getReadLockCount());
557 < //                 assertTrue(t1GotLock.get());
558 < //                 lock.readLock().unlock();
559 < //             }});
560 < //         waitForQueuedThread(lock, t2);
561 < //         assertTrue(t1.isAlive());
562 < //         assertNotWriteLocked(lock);
563 < //         assertEquals(1, lock.getReadLockCount());
564 < //         lock.readLock().unlock();
565 < //         awaitTermination(t1);
566 < //         awaitTermination(t2);
567 < //         assertNotWriteLocked(lock);
568 < //     }
569 <
570 < //     /**
571 < //      * Readlocks succeed only after a writing thread unlocks
572 < //      */
573 < //     public void testReadAfterWriteLock()      { testReadAfterWriteLock(false); }
574 < //     public void testReadAfterWriteLock_fair() { testReadAfterWriteLock(true); }
575 < //     public void testReadAfterWriteLock(boolean fair) {
576 < //         final PublicReentrantReadWriteLock lock =
577 < //             new PublicReentrantReadWriteLock(fair);
578 < //         lock.writeLock().lock();
579 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
580 < //             public void realRun() {
581 < //                 lock.readLock().lock();
582 < //                 lock.readLock().unlock();
583 < //             }});
584 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
585 < //             public void realRun() {
586 < //                 lock.readLock().lock();
587 < //                 lock.readLock().unlock();
588 < //             }});
589 <
590 < //         waitForQueuedThread(lock, t1);
591 < //         waitForQueuedThread(lock, t2);
592 < //         releaseWriteLock(lock);
593 < //         awaitTermination(t1);
594 < //         awaitTermination(t2);
595 < //     }
596 <
597 < //     /**
598 < //      * Read trylock succeeds if write locked by current thread
599 < //      */
600 < //     public void testReadHoldingWriteLock()      { testReadHoldingWriteLock(false); }
601 < //     public void testReadHoldingWriteLock_fair() { testReadHoldingWriteLock(true); }
602 < //     public void testReadHoldingWriteLock(boolean fair) {
603 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
604 < //         lock.writeLock().lock();
605 < //         assertTrue(lock.readLock().tryLock());
606 < //         lock.readLock().unlock();
607 < //         lock.writeLock().unlock();
608 < //     }
609 <
610 < //     /**
611 < //      * Read trylock succeeds (barging) even in the presence of waiting
612 < //      * readers and/or writers
613 < //      */
614 < //     public void testReadTryLockBarging()      { testReadTryLockBarging(false); }
615 < //     public void testReadTryLockBarging_fair() { testReadTryLockBarging(true); }
616 < //     public void testReadTryLockBarging(boolean fair) {
617 < //         final PublicReentrantReadWriteLock lock =
618 < //             new PublicReentrantReadWriteLock(fair);
619 < //         lock.readLock().lock();
620 <
621 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
622 < //             public void realRun() {
623 < //                 lock.writeLock().lock();
624 < //                 lock.writeLock().unlock();
625 < //             }});
626 <
627 < //         waitForQueuedThread(lock, t1);
628 <
629 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
630 < //             public void realRun() {
631 < //                 lock.readLock().lock();
632 < //                 lock.readLock().unlock();
633 < //             }});
634 <
635 < //         if (fair)
636 < //             waitForQueuedThread(lock, t2);
637 <
638 < //         Thread t3 = newStartedThread(new CheckedRunnable() {
639 < //             public void realRun() {
640 < //                 lock.readLock().tryLock();
641 < //                 lock.readLock().unlock();
642 < //             }});
643 <
644 < //         assertTrue(lock.getReadLockCount() > 0);
645 < //         awaitTermination(t3);
646 < //         assertTrue(t1.isAlive());
647 < //         if (fair) assertTrue(t2.isAlive());
648 < //         lock.readLock().unlock();
649 < //         awaitTermination(t1);
650 < //         awaitTermination(t2);
651 < //     }
652 <
653 < //     /**
654 < //      * Read lock succeeds if write locked by current thread even if
655 < //      * other threads are waiting for readlock
656 < //      */
657 < //     public void testReadHoldingWriteLock2()      { testReadHoldingWriteLock2(false); }
658 < //     public void testReadHoldingWriteLock2_fair() { testReadHoldingWriteLock2(true); }
659 < //     public void testReadHoldingWriteLock2(boolean fair) {
660 < //         final PublicReentrantReadWriteLock lock =
661 < //             new PublicReentrantReadWriteLock(fair);
662 < //         lock.writeLock().lock();
663 < //         lock.readLock().lock();
664 < //         lock.readLock().unlock();
665 <
666 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
667 < //             public void realRun() {
668 < //                 lock.readLock().lock();
669 < //                 lock.readLock().unlock();
670 < //             }});
671 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
672 < //             public void realRun() {
673 < //                 lock.readLock().lock();
674 < //                 lock.readLock().unlock();
675 < //             }});
676 <
677 < //         waitForQueuedThread(lock, t1);
678 < //         waitForQueuedThread(lock, t2);
679 < //         assertWriteLockedByMoi(lock);
680 < //         lock.readLock().lock();
681 < //         lock.readLock().unlock();
682 < //         releaseWriteLock(lock);
683 < //         awaitTermination(t1);
684 < //         awaitTermination(t2);
685 < //     }
686 <
687 < //     /**
688 < //      * Read lock succeeds if write locked by current thread even if
689 < //      * other threads are waiting for writelock
690 < //      */
691 < //     public void testReadHoldingWriteLock3()      { testReadHoldingWriteLock3(false); }
692 < //     public void testReadHoldingWriteLock3_fair() { testReadHoldingWriteLock3(true); }
693 < //     public void testReadHoldingWriteLock3(boolean fair) {
694 < //         final PublicReentrantReadWriteLock lock =
695 < //             new PublicReentrantReadWriteLock(fair);
696 < //         lock.writeLock().lock();
697 < //         lock.readLock().lock();
698 < //         lock.readLock().unlock();
699 <
700 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
701 < //             public void realRun() {
702 < //                 lock.writeLock().lock();
703 < //                 lock.writeLock().unlock();
704 < //             }});
705 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
706 < //             public void realRun() {
707 < //                 lock.writeLock().lock();
708 < //                 lock.writeLock().unlock();
709 < //             }});
710 <
711 < //         waitForQueuedThread(lock, t1);
712 < //         waitForQueuedThread(lock, t2);
713 < //         assertWriteLockedByMoi(lock);
714 < //         lock.readLock().lock();
715 < //         lock.readLock().unlock();
716 < //         assertWriteLockedByMoi(lock);
717 < //         lock.writeLock().unlock();
718 < //         awaitTermination(t1);
719 < //         awaitTermination(t2);
720 < //     }
721 <
722 < //     /**
723 < //      * Write lock succeeds if write locked by current thread even if
724 < //      * other threads are waiting for writelock
725 < //      */
726 < //     public void testWriteHoldingWriteLock4()      { testWriteHoldingWriteLock4(false); }
727 < //     public void testWriteHoldingWriteLock4_fair() { testWriteHoldingWriteLock4(true); }
728 < //     public void testWriteHoldingWriteLock4(boolean fair) {
729 < //         final PublicReentrantReadWriteLock lock =
730 < //             new PublicReentrantReadWriteLock(fair);
731 < //         lock.writeLock().lock();
732 < //         lock.writeLock().lock();
733 < //         lock.writeLock().unlock();
734 <
735 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
736 < //             public void realRun() {
737 < //                 lock.writeLock().lock();
738 < //                 lock.writeLock().unlock();
739 < //             }});
740 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
741 < //             public void realRun() {
742 < //                 lock.writeLock().lock();
743 < //                 lock.writeLock().unlock();
744 < //             }});
745 <
746 < //         waitForQueuedThread(lock, t1);
747 < //         waitForQueuedThread(lock, t2);
748 < //         assertWriteLockedByMoi(lock);
749 < //         assertEquals(1, lock.getWriteHoldCount());
750 < //         lock.writeLock().lock();
751 < //         assertWriteLockedByMoi(lock);
752 < //         assertEquals(2, lock.getWriteHoldCount());
753 < //         lock.writeLock().unlock();
754 < //         assertWriteLockedByMoi(lock);
755 < //         assertEquals(1, lock.getWriteHoldCount());
756 < //         lock.writeLock().unlock();
757 < //         awaitTermination(t1);
758 < //         awaitTermination(t2);
759 < //     }
760 <
761 < //     /**
762 < //      * Read tryLock succeeds if readlocked but not writelocked
763 < //      */
764 < //     public void testTryLockWhenReadLocked()      { testTryLockWhenReadLocked(false); }
765 < //     public void testTryLockWhenReadLocked_fair() { testTryLockWhenReadLocked(true); }
766 < //     public void testTryLockWhenReadLocked(boolean fair) {
767 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
768 < //         lock.readLock().lock();
769 < //         Thread t = newStartedThread(new CheckedRunnable() {
770 < //             public void realRun() {
771 < //                 assertTrue(lock.readLock().tryLock());
772 < //                 lock.readLock().unlock();
773 < //             }});
774 <
775 < //         awaitTermination(t);
776 < //         lock.readLock().unlock();
777 < //     }
778 <
779 < //     /**
780 < //      * write tryLock fails when readlocked
781 < //      */
782 < //     public void testWriteTryLockWhenReadLocked()      { testWriteTryLockWhenReadLocked(false); }
783 < //     public void testWriteTryLockWhenReadLocked_fair() { testWriteTryLockWhenReadLocked(true); }
784 < //     public void testWriteTryLockWhenReadLocked(boolean fair) {
785 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
786 < //         lock.readLock().lock();
787 < //         Thread t = newStartedThread(new CheckedRunnable() {
788 < //             public void realRun() {
789 < //                 assertFalse(lock.writeLock().tryLock());
790 < //             }});
791 <
792 < //         awaitTermination(t);
793 < //         lock.readLock().unlock();
794 < //     }
795 <
796 < //     /**
797 < //      * write timed tryLock times out if locked
798 < //      */
799 < //     public void testWriteTryLock_Timeout()      { testWriteTryLock_Timeout(false); }
800 < //     public void testWriteTryLock_Timeout_fair() { testWriteTryLock_Timeout(true); }
801 < //     public void testWriteTryLock_Timeout(boolean fair) {
802 < //         final PublicReentrantReadWriteLock lock =
803 < //             new PublicReentrantReadWriteLock(fair);
804 < //         lock.writeLock().lock();
805 < //         Thread t = newStartedThread(new CheckedRunnable() {
806 < //             public void realRun() throws InterruptedException {
807 < //                 long startTime = System.nanoTime();
808 < //                 long timeoutMillis = 10;
809 < //                 assertFalse(lock.writeLock().tryLock(timeoutMillis, MILLISECONDS));
810 < //                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
811 < //             }});
812 <
813 < //         awaitTermination(t);
814 < //         releaseWriteLock(lock);
815 < //     }
816 <
817 < //     /**
818 < //      * read timed tryLock times out if write-locked
819 < //      */
820 < //     public void testReadTryLock_Timeout()      { testReadTryLock_Timeout(false); }
821 < //     public void testReadTryLock_Timeout_fair() { testReadTryLock_Timeout(true); }
822 < //     public void testReadTryLock_Timeout(boolean fair) {
823 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
824 < //         lock.writeLock().lock();
825 < //         Thread t = newStartedThread(new CheckedRunnable() {
826 < //             public void realRun() throws InterruptedException {
827 < //                 long startTime = System.nanoTime();
828 < //                 long timeoutMillis = 10;
829 < //                 assertFalse(lock.readLock().tryLock(timeoutMillis, MILLISECONDS));
830 < //                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
831 < //             }});
832 <
833 < //         awaitTermination(t);
834 < //         assertTrue(lock.writeLock().isHeldByCurrentThread());
835 < //         lock.writeLock().unlock();
836 < //     }
837 <
838 < //     /**
839 < //      * write lockInterruptibly succeeds if unlocked, else is interruptible
840 < //      */
841 < //     public void testWriteLockInterruptibly()      { testWriteLockInterruptibly(false); }
842 < //     public void testWriteLockInterruptibly_fair() { testWriteLockInterruptibly(true); }
843 < //     public void testWriteLockInterruptibly(boolean fair) {
844 < //         final PublicReentrantReadWriteLock lock =
845 < //             new PublicReentrantReadWriteLock(fair);
846 < //         try {
847 < //             lock.writeLock().lockInterruptibly();
848 < //         } catch (InterruptedException ie) {
849 < //             threadUnexpectedException(ie);
850 < //         }
851 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
852 < //             public void realRun() throws InterruptedException {
853 < //                 lock.writeLock().lockInterruptibly();
854 < //             }});
855 <
856 < //         waitForQueuedThread(lock, t);
857 < //         t.interrupt();
858 < //         assertTrue(lock.writeLock().isHeldByCurrentThread());
859 < //         awaitTermination(t);
860 < //         releaseWriteLock(lock);
861 < //     }
862 <
863 < //     /**
864 < //      * read lockInterruptibly succeeds if lock free else is interruptible
865 < //      */
866 < //     public void testReadLockInterruptibly()      { testReadLockInterruptibly(false); }
867 < //     public void testReadLockInterruptibly_fair() { testReadLockInterruptibly(true); }
868 < //     public void testReadLockInterruptibly(boolean fair) {
869 < //         final PublicReentrantReadWriteLock lock =
870 < //             new PublicReentrantReadWriteLock(fair);
871 < //         try {
872 < //             lock.readLock().lockInterruptibly();
873 < //             lock.readLock().unlock();
874 < //             lock.writeLock().lockInterruptibly();
875 < //         } catch (InterruptedException ie) {
876 < //             threadUnexpectedException(ie);
877 < //         }
878 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
879 < //             public void realRun() throws InterruptedException {
880 < //                 lock.readLock().lockInterruptibly();
881 < //             }});
882 <
883 < //         waitForQueuedThread(lock, t);
884 < //         t.interrupt();
885 < //         awaitTermination(t);
886 < //         releaseWriteLock(lock);
887 < //     }
888 <
889 < //     /**
890 < //      * Calling await without holding lock throws IllegalMonitorStateException
891 < //      */
892 < //     public void testAwait_IMSE()      { testAwait_IMSE(false); }
893 < //     public void testAwait_IMSE_fair() { testAwait_IMSE(true); }
894 < //     public void testAwait_IMSE(boolean fair) {
895 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
896 < //         final Condition c = lock.writeLock().newCondition();
897 < //         for (AwaitMethod awaitMethod : AwaitMethod.values()) {
898 < //             long startTime = System.nanoTime();
899 < //             try {
900 < //                 await(c, awaitMethod);
901 < //                 shouldThrow();
902 < //             } catch (IllegalMonitorStateException success) {
903 < //             } catch (InterruptedException e) { threadUnexpectedException(e); }
904 < //             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
905 < //         }
906 < //     }
907 <
908 < //     /**
909 < //      * Calling signal without holding lock throws IllegalMonitorStateException
910 < //      */
911 < //     public void testSignal_IMSE()      { testSignal_IMSE(false); }
912 < //     public void testSignal_IMSE_fair() { testSignal_IMSE(true); }
913 < //     public void testSignal_IMSE(boolean fair) {
914 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
915 < //         final Condition c = lock.writeLock().newCondition();
916 < //         try {
917 < //             c.signal();
918 < //             shouldThrow();
919 < //         } catch (IllegalMonitorStateException success) {}
920 < //     }
921 <
922 < //     /**
923 < //      * Calling signalAll without holding lock throws IllegalMonitorStateException
924 < //      */
925 < //     public void testSignalAll_IMSE()      { testSignalAll_IMSE(false); }
926 < //     public void testSignalAll_IMSE_fair() { testSignalAll_IMSE(true); }
927 < //     public void testSignalAll_IMSE(boolean fair) {
928 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
929 < //         final Condition c = lock.writeLock().newCondition();
930 < //         try {
931 < //             c.signalAll();
932 < //             shouldThrow();
933 < //         } catch (IllegalMonitorStateException success) {}
934 < //     }
935 <
936 < //     /**
937 < //      * awaitNanos without a signal times out
938 < //      */
939 < //     public void testAwaitNanos_Timeout()      { testAwaitNanos_Timeout(false); }
940 < //     public void testAwaitNanos_Timeout_fair() { testAwaitNanos_Timeout(true); }
941 < //     public void testAwaitNanos_Timeout(boolean fair) {
942 < //         try {
943 < //             final ReentrantReadWriteLock lock =
944 < //                 new ReentrantReadWriteLock(fair);
945 < //             final Condition c = lock.writeLock().newCondition();
946 < //             lock.writeLock().lock();
947 < //             long startTime = System.nanoTime();
948 < //             long timeoutMillis = 10;
949 < //             long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
950 < //             long nanosRemaining = c.awaitNanos(timeoutNanos);
951 < //             assertTrue(nanosRemaining <= 0);
952 < //             assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
953 < //             lock.writeLock().unlock();
954 < //         } catch (InterruptedException e) {
955 < //             threadUnexpectedException(e);
956 < //         }
957 < //     }
958 <
959 < //     /**
960 < //      * timed await without a signal times out
961 < //      */
962 < //     public void testAwait_Timeout()      { testAwait_Timeout(false); }
963 < //     public void testAwait_Timeout_fair() { testAwait_Timeout(true); }
964 < //     public void testAwait_Timeout(boolean fair) {
965 < //         try {
966 < //             final ReentrantReadWriteLock lock =
967 < //                 new ReentrantReadWriteLock(fair);
968 < //             final Condition c = lock.writeLock().newCondition();
969 < //             lock.writeLock().lock();
970 < //             long startTime = System.nanoTime();
971 < //             long timeoutMillis = 10;
972 < //             assertFalse(c.await(timeoutMillis, MILLISECONDS));
973 < //             assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
974 < //             lock.writeLock().unlock();
975 < //         } catch (InterruptedException e) {
976 < //             threadUnexpectedException(e);
977 < //         }
978 < //     }
979 <
980 < //     /**
981 < //      * awaitUntil without a signal times out
982 < //      */
983 < //     public void testAwaitUntil_Timeout()      { testAwaitUntil_Timeout(false); }
984 < //     public void testAwaitUntil_Timeout_fair() { testAwaitUntil_Timeout(true); }
985 < //     public void testAwaitUntil_Timeout(boolean fair) {
986 < //         try {
987 < //             final ReentrantReadWriteLock lock =
988 < //                 new ReentrantReadWriteLock(fair);
989 < //             final Condition c = lock.writeLock().newCondition();
990 < //             lock.writeLock().lock();
991 < //             long startTime = System.nanoTime();
992 < //             long timeoutMillis = 10;
993 < //             java.util.Date d = new java.util.Date();
994 < //             assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + timeoutMillis)));
995 < //             assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
996 < //             lock.writeLock().unlock();
997 < //         } catch (InterruptedException e) {
998 < //             threadUnexpectedException(e);
999 < //         }
1000 < //     }
1001 <
1002 < //     /**
1003 < //      * await returns when signalled
1004 < //      */
1005 < //     public void testAwait()      { testAwait(false); }
1006 < //     public void testAwait_fair() { testAwait(true); }
1007 < //     public void testAwait(boolean fair) {
1008 < //         final PublicReentrantReadWriteLock lock =
1009 < //             new PublicReentrantReadWriteLock(fair);
1010 < //         final Condition c = lock.writeLock().newCondition();
1011 < //         final CountDownLatch locked = new CountDownLatch(1);
1012 < //         Thread t = newStartedThread(new CheckedRunnable() {
1013 < //             public void realRun() throws InterruptedException {
1014 < //                 lock.writeLock().lock();
1015 < //                 locked.countDown();
1016 < //                 c.await();
1017 < //                 lock.writeLock().unlock();
1018 < //             }});
1019 <
1020 < //         await(locked);
1021 < //         lock.writeLock().lock();
1022 < //         assertHasWaiters(lock, c, t);
1023 < //         c.signal();
1024 < //         assertHasNoWaiters(lock, c);
1025 < //         assertTrue(t.isAlive());
1026 < //         lock.writeLock().unlock();
1027 < //         awaitTermination(t);
1028 < //     }
1029 <
1030 < //     /**
1031 < //      * awaitUninterruptibly is uninterruptible
1032 < //      */
1033 < //     public void testAwaitUninterruptibly()      { testAwaitUninterruptibly(false); }
1034 < //     public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
1035 < //     public void testAwaitUninterruptibly(boolean fair) {
1036 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1037 < //         final Condition c = lock.writeLock().newCondition();
1038 < //         final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
1039 <
1040 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
1041 < //             public void realRun() {
1042 < //                 // Interrupt before awaitUninterruptibly
1043 < //                 lock.writeLock().lock();
1044 < //                 pleaseInterrupt.countDown();
1045 < //                 Thread.currentThread().interrupt();
1046 < //                 c.awaitUninterruptibly();
1047 < //                 assertTrue(Thread.interrupted());
1048 < //                 lock.writeLock().unlock();
1049 < //             }});
1050 <
1051 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
1052 < //             public void realRun() {
1053 < //                 // Interrupt during awaitUninterruptibly
1054 < //                 lock.writeLock().lock();
1055 < //                 pleaseInterrupt.countDown();
1056 < //                 c.awaitUninterruptibly();
1057 < //                 assertTrue(Thread.interrupted());
1058 < //                 lock.writeLock().unlock();
1059 < //             }});
1060 <
1061 < //         await(pleaseInterrupt);
1062 < //         lock.writeLock().lock();
1063 < //         lock.writeLock().unlock();
1064 < //         t2.interrupt();
1065 <
1066 < //         assertThreadStaysAlive(t1);
1067 < //         assertTrue(t2.isAlive());
1068 <
1069 < //         lock.writeLock().lock();
1070 < //         c.signalAll();
1071 < //         lock.writeLock().unlock();
1072 <
1073 < //         awaitTermination(t1);
1074 < //         awaitTermination(t2);
1075 < //     }
1076 <
1077 < //     /**
1078 < //      * await/awaitNanos/awaitUntil is interruptible
1079 < //      */
1080 < //     public void testInterruptible_await()           { testInterruptible(false, AwaitMethod.await); }
1081 < //     public void testInterruptible_await_fair()      { testInterruptible(true,  AwaitMethod.await); }
1082 < //     public void testInterruptible_awaitTimed()      { testInterruptible(false, AwaitMethod.awaitTimed); }
1083 < //     public void testInterruptible_awaitTimed_fair() { testInterruptible(true,  AwaitMethod.awaitTimed); }
1084 < //     public void testInterruptible_awaitNanos()      { testInterruptible(false, AwaitMethod.awaitNanos); }
1085 < //     public void testInterruptible_awaitNanos_fair() { testInterruptible(true,  AwaitMethod.awaitNanos); }
1086 < //     public void testInterruptible_awaitUntil()      { testInterruptible(false, AwaitMethod.awaitUntil); }
1087 < //     public void testInterruptible_awaitUntil_fair() { testInterruptible(true,  AwaitMethod.awaitUntil); }
1088 < //     public void testInterruptible(boolean fair, final AwaitMethod awaitMethod) {
1089 < //         final PublicReentrantReadWriteLock lock =
1090 < //             new PublicReentrantReadWriteLock(fair);
1091 < //         final Condition c = lock.writeLock().newCondition();
1092 < //         final CountDownLatch locked = new CountDownLatch(1);
1093 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1094 < //             public void realRun() throws InterruptedException {
1095 < //                 lock.writeLock().lock();
1096 < //                 assertWriteLockedByMoi(lock);
1097 < //                 assertHasNoWaiters(lock, c);
1098 < //                 locked.countDown();
1099 < //                 try {
1100 < //                     await(c, awaitMethod);
1101 < //                 } finally {
1102 < //                     assertWriteLockedByMoi(lock);
1103 < //                     assertHasNoWaiters(lock, c);
1104 < //                     lock.writeLock().unlock();
1105 < //                     assertFalse(Thread.interrupted());
1106 < //                 }
1107 < //             }});
1108 <
1109 < //         await(locked);
1110 < //         assertHasWaiters(lock, c, t);
1111 < //         t.interrupt();
1112 < //         awaitTermination(t);
1113 < //         assertNotWriteLocked(lock);
1114 < //     }
1115 <
1116 < //     /**
1117 < //      * signalAll wakes up all threads
1118 < //      */
1119 < //     public void testSignalAll_await()           { testSignalAll(false, AwaitMethod.await); }
1120 < //     public void testSignalAll_await_fair()      { testSignalAll(true,  AwaitMethod.await); }
1121 < //     public void testSignalAll_awaitTimed()      { testSignalAll(false, AwaitMethod.awaitTimed); }
1122 < //     public void testSignalAll_awaitTimed_fair() { testSignalAll(true,  AwaitMethod.awaitTimed); }
1123 < //     public void testSignalAll_awaitNanos()      { testSignalAll(false, AwaitMethod.awaitNanos); }
1124 < //     public void testSignalAll_awaitNanos_fair() { testSignalAll(true,  AwaitMethod.awaitNanos); }
1125 < //     public void testSignalAll_awaitUntil()      { testSignalAll(false, AwaitMethod.awaitUntil); }
1126 < //     public void testSignalAll_awaitUntil_fair() { testSignalAll(true,  AwaitMethod.awaitUntil); }
1127 < //     public void testSignalAll(boolean fair, final AwaitMethod awaitMethod) {
1128 < //         final PublicReentrantReadWriteLock lock =
1129 < //             new PublicReentrantReadWriteLock(fair);
1130 < //         final Condition c = lock.writeLock().newCondition();
1131 < //         final CountDownLatch locked = new CountDownLatch(2);
1132 < //         final Lock writeLock = lock.writeLock();
1133 < //         class Awaiter extends CheckedRunnable {
1134 < //             public void realRun() throws InterruptedException {
1135 < //                 writeLock.lock();
1136 < //                 locked.countDown();
1137 < //                 await(c, awaitMethod);
1138 < //                 writeLock.unlock();
1139 < //             }
1140 < //         }
1141 <
1142 < //         Thread t1 = newStartedThread(new Awaiter());
1143 < //         Thread t2 = newStartedThread(new Awaiter());
1144 <
1145 < //         await(locked);
1146 < //         writeLock.lock();
1147 < //         assertHasWaiters(lock, c, t1, t2);
1148 < //         c.signalAll();
1149 < //         assertHasNoWaiters(lock, c);
1150 < //         writeLock.unlock();
1151 < //         awaitTermination(t1);
1152 < //         awaitTermination(t2);
1153 < //     }
1154 <
1155 < //     /**
1156 < //      * signal wakes up waiting threads in FIFO order
1157 < //      */
1158 < //     public void testSignalWakesFifo()      { testSignalWakesFifo(false); }
1159 < //     public void testSignalWakesFifo_fair() { testSignalWakesFifo(true); }
1160 < //     public void testSignalWakesFifo(boolean fair) {
1161 < //         final PublicReentrantReadWriteLock lock =
1162 < //             new PublicReentrantReadWriteLock(fair);
1163 < //         final Condition c = lock.writeLock().newCondition();
1164 < //         final CountDownLatch locked1 = new CountDownLatch(1);
1165 < //         final CountDownLatch locked2 = new CountDownLatch(1);
1166 < //         final Lock writeLock = lock.writeLock();
1167 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
1168 < //             public void realRun() throws InterruptedException {
1169 < //                 writeLock.lock();
1170 < //                 locked1.countDown();
1171 < //                 c.await();
1172 < //                 writeLock.unlock();
1173 < //             }});
1174 <
1175 < //         await(locked1);
1176 <
1177 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
1178 < //             public void realRun() throws InterruptedException {
1179 < //                 writeLock.lock();
1180 < //                 locked2.countDown();
1181 < //                 c.await();
1182 < //                 writeLock.unlock();
1183 < //             }});
1184 <
1185 < //         await(locked2);
1186 <
1187 < //         writeLock.lock();
1188 < //         assertHasWaiters(lock, c, t1, t2);
1189 < //         assertFalse(lock.hasQueuedThreads());
1190 < //         c.signal();
1191 < //         assertHasWaiters(lock, c, t2);
1192 < //         assertTrue(lock.hasQueuedThread(t1));
1193 < //         assertFalse(lock.hasQueuedThread(t2));
1194 < //         c.signal();
1195 < //         assertHasNoWaiters(lock, c);
1196 < //         assertTrue(lock.hasQueuedThread(t1));
1197 < //         assertTrue(lock.hasQueuedThread(t2));
1198 < //         writeLock.unlock();
1199 < //         awaitTermination(t1);
1200 < //         awaitTermination(t2);
1201 < //     }
1202 <
1203 < //     /**
1204 < //      * await after multiple reentrant locking preserves lock count
1205 < //      */
1206 < //     public void testAwaitLockCount()      { testAwaitLockCount(false); }
1207 < //     public void testAwaitLockCount_fair() { testAwaitLockCount(true); }
1208 < //     public void testAwaitLockCount(boolean fair) {
1209 < //         final PublicReentrantReadWriteLock lock =
1210 < //             new PublicReentrantReadWriteLock(fair);
1211 < //         final Condition c = lock.writeLock().newCondition();
1212 < //         final CountDownLatch locked = new CountDownLatch(2);
1213 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
1214 < //             public void realRun() throws InterruptedException {
1215 < //                 lock.writeLock().lock();
1216 < //                 assertWriteLockedByMoi(lock);
1217 < //                 assertEquals(1, lock.writeLock().getHoldCount());
1218 < //                 locked.countDown();
1219 < //                 c.await();
1220 < //                 assertWriteLockedByMoi(lock);
1221 < //                 assertEquals(1, lock.writeLock().getHoldCount());
1222 < //                 lock.writeLock().unlock();
1223 < //             }});
1224 <
1225 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
1226 < //             public void realRun() throws InterruptedException {
1227 < //                 lock.writeLock().lock();
1228 < //                 lock.writeLock().lock();
1229 < //                 assertWriteLockedByMoi(lock);
1230 < //                 assertEquals(2, lock.writeLock().getHoldCount());
1231 < //                 locked.countDown();
1232 < //                 c.await();
1233 < //                 assertWriteLockedByMoi(lock);
1234 < //                 assertEquals(2, lock.writeLock().getHoldCount());
1235 < //                 lock.writeLock().unlock();
1236 < //                 lock.writeLock().unlock();
1237 < //             }});
1238 <
1239 < //         await(locked);
1240 < //         lock.writeLock().lock();
1241 < //         assertHasWaiters(lock, c, t1, t2);
1242 < //         c.signalAll();
1243 < //         assertHasNoWaiters(lock, c);
1244 < //         lock.writeLock().unlock();
1245 < //         awaitTermination(t1);
1246 < //         awaitTermination(t2);
1247 < //     }
1248 <
1249 < //     /**
1250 < //      * A serialized lock deserializes as unlocked
1251 < //      */
1252 < //     public void testSerialization()      { testSerialization(false); }
1253 < //     public void testSerialization_fair() { testSerialization(true); }
1254 < //     public void testSerialization(boolean fair) {
1255 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1256 < //         lock.writeLock().lock();
1257 < //         lock.readLock().lock();
1258 <
1259 < //         ReentrantReadWriteLock clone = serialClone(lock);
1260 < //         assertEquals(lock.isFair(), clone.isFair());
1261 < //         assertTrue(lock.isWriteLocked());
1262 < //         assertFalse(clone.isWriteLocked());
1263 < //         assertEquals(1, lock.getReadLockCount());
1264 < //         assertEquals(0, clone.getReadLockCount());
1265 < //         clone.writeLock().lock();
1266 < //         clone.readLock().lock();
1267 < //         assertTrue(clone.isWriteLocked());
1268 < //         assertEquals(1, clone.getReadLockCount());
1269 < //         clone.readLock().unlock();
1270 < //         clone.writeLock().unlock();
1271 < //         assertFalse(clone.isWriteLocked());
1272 < //         assertEquals(1, lock.getReadLockCount());
1273 < //         assertEquals(0, clone.getReadLockCount());
1274 < //     }
1275 <
1276 < //     /**
1277 < //      * hasQueuedThreads reports whether there are waiting threads
1278 < //      */
1279 < //     public void testHasQueuedThreads()      { testHasQueuedThreads(false); }
1280 < //     public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
1281 < //     public void testHasQueuedThreads(boolean fair) {
1282 < //         final PublicReentrantReadWriteLock lock =
1283 < //             new PublicReentrantReadWriteLock(fair);
1284 < //         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1285 < //         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1286 < //         assertFalse(lock.hasQueuedThreads());
1287 < //         lock.writeLock().lock();
1288 < //         assertFalse(lock.hasQueuedThreads());
1289 < //         t1.start();
1290 < //         waitForQueuedThread(lock, t1);
1291 < //         assertTrue(lock.hasQueuedThreads());
1292 < //         t2.start();
1293 < //         waitForQueuedThread(lock, t2);
1294 < //         assertTrue(lock.hasQueuedThreads());
1295 < //         t1.interrupt();
1296 < //         awaitTermination(t1);
1297 < //         assertTrue(lock.hasQueuedThreads());
1298 < //         lock.writeLock().unlock();
1299 < //         awaitTermination(t2);
1300 < //         assertFalse(lock.hasQueuedThreads());
1301 < //     }
1302 <
1303 < //     /**
1304 < //      * hasQueuedThread(null) throws NPE
1305 < //      */
1306 < //     public void testHasQueuedThreadNPE()      { testHasQueuedThreadNPE(false); }
1307 < //     public void testHasQueuedThreadNPE_fair() { testHasQueuedThreadNPE(true); }
1308 < //     public void testHasQueuedThreadNPE(boolean fair) {
1309 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1310 < //         try {
1311 < //             lock.hasQueuedThread(null);
1312 < //             shouldThrow();
1313 < //         } catch (NullPointerException success) {}
1314 < //     }
1315 <
1316 < //     /**
1317 < //      * hasQueuedThread reports whether a thread is queued
1318 < //      */
1319 < //     public void testHasQueuedThread()      { testHasQueuedThread(false); }
1320 < //     public void testHasQueuedThread_fair() { testHasQueuedThread(true); }
1321 < //     public void testHasQueuedThread(boolean fair) {
1322 < //         final PublicReentrantReadWriteLock lock =
1323 < //             new PublicReentrantReadWriteLock(fair);
1324 < //         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1325 < //         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1326 < //         assertFalse(lock.hasQueuedThread(t1));
1327 < //         assertFalse(lock.hasQueuedThread(t2));
1328 < //         lock.writeLock().lock();
1329 < //         t1.start();
1330 < //         waitForQueuedThread(lock, t1);
1331 < //         assertTrue(lock.hasQueuedThread(t1));
1332 < //         assertFalse(lock.hasQueuedThread(t2));
1333 < //         t2.start();
1334 < //         waitForQueuedThread(lock, t2);
1335 < //         assertTrue(lock.hasQueuedThread(t1));
1336 < //         assertTrue(lock.hasQueuedThread(t2));
1337 < //         t1.interrupt();
1338 < //         awaitTermination(t1);
1339 < //         assertFalse(lock.hasQueuedThread(t1));
1340 < //         assertTrue(lock.hasQueuedThread(t2));
1341 < //         lock.writeLock().unlock();
1342 < //         awaitTermination(t2);
1343 < //         assertFalse(lock.hasQueuedThread(t1));
1344 < //         assertFalse(lock.hasQueuedThread(t2));
1345 < //     }
1346 <
1347 < //     /**
1348 < //      * getQueueLength reports number of waiting threads
1349 < //      */
1350 < //     public void testGetQueueLength()      { testGetQueueLength(false); }
1351 < //     public void testGetQueueLength_fair() { testGetQueueLength(true); }
1352 < //     public void testGetQueueLength(boolean fair) {
1353 < //         final PublicReentrantReadWriteLock lock =
1354 < //             new PublicReentrantReadWriteLock(fair);
1355 < //         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1356 < //         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1357 < //         assertEquals(0, lock.getQueueLength());
1358 < //         lock.writeLock().lock();
1359 < //         t1.start();
1360 < //         waitForQueuedThread(lock, t1);
1361 < //         assertEquals(1, lock.getQueueLength());
1362 < //         t2.start();
1363 < //         waitForQueuedThread(lock, t2);
1364 < //         assertEquals(2, lock.getQueueLength());
1365 < //         t1.interrupt();
1366 < //         awaitTermination(t1);
1367 < //         assertEquals(1, lock.getQueueLength());
1368 < //         lock.writeLock().unlock();
1369 < //         awaitTermination(t2);
1370 < //         assertEquals(0, lock.getQueueLength());
1371 < //     }
1372 <
1373 < //     /**
1374 < //      * getQueuedThreads includes waiting threads
1375 < //      */
1376 < //     public void testGetQueuedThreads()      { testGetQueuedThreads(false); }
1377 < //     public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
1378 < //     public void testGetQueuedThreads(boolean fair) {
1379 < //         final PublicReentrantReadWriteLock lock =
1380 < //             new PublicReentrantReadWriteLock(fair);
1381 < //         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1382 < //         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1383 < //         assertTrue(lock.getQueuedThreads().isEmpty());
1384 < //         lock.writeLock().lock();
1385 < //         assertTrue(lock.getQueuedThreads().isEmpty());
1386 < //         t1.start();
1387 < //         waitForQueuedThread(lock, t1);
1388 < //         assertEquals(1, lock.getQueuedThreads().size());
1389 < //         assertTrue(lock.getQueuedThreads().contains(t1));
1390 < //         t2.start();
1391 < //         waitForQueuedThread(lock, t2);
1392 < //         assertEquals(2, lock.getQueuedThreads().size());
1393 < //         assertTrue(lock.getQueuedThreads().contains(t1));
1394 < //         assertTrue(lock.getQueuedThreads().contains(t2));
1395 < //         t1.interrupt();
1396 < //         awaitTermination(t1);
1397 < //         assertFalse(lock.getQueuedThreads().contains(t1));
1398 < //         assertTrue(lock.getQueuedThreads().contains(t2));
1399 < //         assertEquals(1, lock.getQueuedThreads().size());
1400 < //         lock.writeLock().unlock();
1401 < //         awaitTermination(t2);
1402 < //         assertTrue(lock.getQueuedThreads().isEmpty());
1403 < //     }
1404 <
1405 < //     /**
1406 < //      * hasWaiters throws NPE if null
1407 < //      */
1408 < //     public void testHasWaitersNPE()      { testHasWaitersNPE(false); }
1409 < //     public void testHasWaitersNPE_fair() { testHasWaitersNPE(true); }
1410 < //     public void testHasWaitersNPE(boolean fair) {
1411 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1412 < //         try {
1413 < //             lock.hasWaiters(null);
1414 < //             shouldThrow();
1415 < //         } catch (NullPointerException success) {}
1416 < //     }
1417 <
1418 < //     /**
1419 < //      * getWaitQueueLength throws NPE if null
1420 < //      */
1421 < //     public void testGetWaitQueueLengthNPE()      { testGetWaitQueueLengthNPE(false); }
1422 < //     public void testGetWaitQueueLengthNPE_fair() { testGetWaitQueueLengthNPE(true); }
1423 < //     public void testGetWaitQueueLengthNPE(boolean fair) {
1424 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1425 < //         try {
1426 < //             lock.getWaitQueueLength(null);
1427 < //             shouldThrow();
1428 < //         } catch (NullPointerException success) {}
1429 < //     }
1430 <
1431 < //     /**
1432 < //      * getWaitingThreads throws NPE if null
1433 < //      */
1434 < //     public void testGetWaitingThreadsNPE()      { testGetWaitingThreadsNPE(false); }
1435 < //     public void testGetWaitingThreadsNPE_fair() { testGetWaitingThreadsNPE(true); }
1436 < //     public void testGetWaitingThreadsNPE(boolean fair) {
1437 < //         final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(fair);
1438 < //         try {
1439 < //             lock.getWaitingThreads(null);
1440 < //             shouldThrow();
1441 < //         } catch (NullPointerException success) {}
1442 < //     }
1443 <
1444 < //     /**
1445 < //      * hasWaiters throws IllegalArgumentException if not owned
1446 < //      */
1447 < //     public void testHasWaitersIAE()      { testHasWaitersIAE(false); }
1448 < //     public void testHasWaitersIAE_fair() { testHasWaitersIAE(true); }
1449 < //     public void testHasWaitersIAE(boolean fair) {
1450 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1451 < //         final Condition c = lock.writeLock().newCondition();
1452 < //         final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(fair);
1453 < //         try {
1454 < //             lock2.hasWaiters(c);
1455 < //             shouldThrow();
1456 < //         } catch (IllegalArgumentException success) {}
1457 < //     }
1458 <
1459 < //     /**
1460 < //      * hasWaiters throws IllegalMonitorStateException if not locked
1461 < //      */
1462 < //     public void testHasWaitersIMSE()      { testHasWaitersIMSE(false); }
1463 < //     public void testHasWaitersIMSE_fair() { testHasWaitersIMSE(true); }
1464 < //     public void testHasWaitersIMSE(boolean fair) {
1465 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1466 < //         final Condition c = lock.writeLock().newCondition();
1467 < //         try {
1468 < //             lock.hasWaiters(c);
1469 < //             shouldThrow();
1470 < //         } catch (IllegalMonitorStateException success) {}
1471 < //     }
1472 <
1473 < //     /**
1474 < //      * getWaitQueueLength throws IllegalArgumentException if not owned
1475 < //      */
1476 < //     public void testGetWaitQueueLengthIAE()      { testGetWaitQueueLengthIAE(false); }
1477 < //     public void testGetWaitQueueLengthIAE_fair() { testGetWaitQueueLengthIAE(true); }
1478 < //     public void testGetWaitQueueLengthIAE(boolean fair) {
1479 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1480 < //         final Condition c = lock.writeLock().newCondition();
1481 < //         final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(fair);
1482 < //         try {
1483 < //             lock2.getWaitQueueLength(c);
1484 < //             shouldThrow();
1485 < //         } catch (IllegalArgumentException success) {}
1486 < //     }
1487 <
1488 < //     /**
1489 < //      * getWaitQueueLength throws IllegalMonitorStateException if not locked
1490 < //      */
1491 < //     public void testGetWaitQueueLengthIMSE()      { testGetWaitQueueLengthIMSE(false); }
1492 < //     public void testGetWaitQueueLengthIMSE_fair() { testGetWaitQueueLengthIMSE(true); }
1493 < //     public void testGetWaitQueueLengthIMSE(boolean fair) {
1494 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1495 < //         final Condition c = lock.writeLock().newCondition();
1496 < //         try {
1497 < //             lock.getWaitQueueLength(c);
1498 < //             shouldThrow();
1499 < //         } catch (IllegalMonitorStateException success) {}
1500 < //     }
1501 <
1488 < //     /**
1489 < //      * getWaitingThreads throws IllegalArgumentException if not owned
1490 < //      */
1491 < //     public void testGetWaitingThreadsIAE()      { testGetWaitingThreadsIAE(false); }
1492 < //     public void testGetWaitingThreadsIAE_fair() { testGetWaitingThreadsIAE(true); }
1493 < //     public void testGetWaitingThreadsIAE(boolean fair) {
1494 < //         final PublicReentrantReadWriteLock lock =
1495 < //             new PublicReentrantReadWriteLock(fair);
1496 < //         final Condition c = lock.writeLock().newCondition();
1497 < //         final PublicReentrantReadWriteLock lock2 =
1498 < //             new PublicReentrantReadWriteLock(fair);
1499 < //         try {
1500 < //             lock2.getWaitingThreads(c);
1501 < //             shouldThrow();
1502 < //         } catch (IllegalArgumentException success) {}
1503 < //     }
1504 <
1505 < //     /**
1506 < //      * getWaitingThreads throws IllegalMonitorStateException if not locked
1507 < //      */
1508 < //     public void testGetWaitingThreadsIMSE()      { testGetWaitingThreadsIMSE(false); }
1509 < //     public void testGetWaitingThreadsIMSE_fair() { testGetWaitingThreadsIMSE(true); }
1510 < //     public void testGetWaitingThreadsIMSE(boolean fair) {
1511 < //         final PublicReentrantReadWriteLock lock =
1512 < //             new PublicReentrantReadWriteLock(fair);
1513 < //         final Condition c = lock.writeLock().newCondition();
1514 < //         try {
1515 < //             lock.getWaitingThreads(c);
1516 < //             shouldThrow();
1517 < //         } catch (IllegalMonitorStateException success) {}
1518 < //     }
1519 <
1520 < //     /**
1521 < //      * hasWaiters returns true when a thread is waiting, else false
1522 < //      */
1523 < //     public void testHasWaiters()      { testHasWaiters(false); }
1524 < //     public void testHasWaiters_fair() { testHasWaiters(true); }
1525 < //     public void testHasWaiters(boolean fair) {
1526 < //         final PublicReentrantReadWriteLock lock =
1527 < //             new PublicReentrantReadWriteLock(fair);
1528 < //         final Condition c = lock.writeLock().newCondition();
1529 < //         final CountDownLatch locked = new CountDownLatch(1);
1530 < //         Thread t = newStartedThread(new CheckedRunnable() {
1531 < //             public void realRun() throws InterruptedException {
1532 < //                 lock.writeLock().lock();
1533 < //                 assertHasNoWaiters(lock, c);
1534 < //                 assertFalse(lock.hasWaiters(c));
1535 < //                 locked.countDown();
1536 < //                 c.await();
1537 < //                 assertHasNoWaiters(lock, c);
1538 < //                 assertFalse(lock.hasWaiters(c));
1539 < //                 lock.writeLock().unlock();
1540 < //             }});
1541 <
1542 < //         await(locked);
1543 < //         lock.writeLock().lock();
1544 < //         assertHasWaiters(lock, c, t);
1545 < //         assertTrue(lock.hasWaiters(c));
1546 < //         c.signal();
1547 < //         assertHasNoWaiters(lock, c);
1548 < //         assertFalse(lock.hasWaiters(c));
1549 < //         lock.writeLock().unlock();
1550 < //         awaitTermination(t);
1551 < //         assertHasNoWaiters(lock, c);
1552 < //     }
1553 <
1554 < //     /**
1555 < //      * getWaitQueueLength returns number of waiting threads
1556 < //      */
1557 < //     public void testGetWaitQueueLength()      { testGetWaitQueueLength(false); }
1558 < //     public void testGetWaitQueueLength_fair() { testGetWaitQueueLength(true); }
1559 < //     public void testGetWaitQueueLength(boolean fair) {
1560 < //         final PublicReentrantReadWriteLock lock =
1561 < //             new PublicReentrantReadWriteLock(fair);
1562 < //         final Condition c = lock.writeLock().newCondition();
1563 < //         final CountDownLatch locked = new CountDownLatch(1);
1564 < //         Thread t = newStartedThread(new CheckedRunnable() {
1565 < //             public void realRun() throws InterruptedException {
1566 < //                 lock.writeLock().lock();
1567 < //                 assertEquals(0, lock.getWaitQueueLength(c));
1568 < //                 locked.countDown();
1569 < //                 c.await();
1570 < //                 lock.writeLock().unlock();
1571 < //             }});
1572 <
1573 < //         await(locked);
1574 < //         lock.writeLock().lock();
1575 < //         assertHasWaiters(lock, c, t);
1576 < //         assertEquals(1, lock.getWaitQueueLength(c));
1577 < //         c.signal();
1578 < //         assertHasNoWaiters(lock, c);
1579 < //         assertEquals(0, lock.getWaitQueueLength(c));
1580 < //         lock.writeLock().unlock();
1581 < //         awaitTermination(t);
1582 < //     }
1583 <
1584 < //     /**
1585 < //      * getWaitingThreads returns only and all waiting threads
1586 < //      */
1587 < //     public void testGetWaitingThreads()      { testGetWaitingThreads(false); }
1588 < //     public void testGetWaitingThreads_fair() { testGetWaitingThreads(true); }
1589 < //     public void testGetWaitingThreads(boolean fair) {
1590 < //         final PublicReentrantReadWriteLock lock =
1591 < //             new PublicReentrantReadWriteLock(fair);
1592 < //         final Condition c = lock.writeLock().newCondition();
1593 < //         final CountDownLatch locked1 = new CountDownLatch(1);
1594 < //         final CountDownLatch locked2 = new CountDownLatch(1);
1595 < //         Thread t1 = new Thread(new CheckedRunnable() {
1596 < //             public void realRun() throws InterruptedException {
1597 < //                 lock.writeLock().lock();
1598 < //                 assertTrue(lock.getWaitingThreads(c).isEmpty());
1599 < //                 locked1.countDown();
1600 < //                 c.await();
1601 < //                 lock.writeLock().unlock();
1602 < //             }});
1603 <
1604 < //         Thread t2 = new Thread(new CheckedRunnable() {
1605 < //             public void realRun() throws InterruptedException {
1606 < //                 lock.writeLock().lock();
1607 < //                 assertFalse(lock.getWaitingThreads(c).isEmpty());
1608 < //                 locked2.countDown();
1609 < //                 c.await();
1610 < //                 lock.writeLock().unlock();
1611 < //             }});
1612 <
1613 < //         lock.writeLock().lock();
1614 < //         assertTrue(lock.getWaitingThreads(c).isEmpty());
1615 < //         lock.writeLock().unlock();
1616 <
1617 < //         t1.start();
1618 < //         await(locked1);
1619 < //         t2.start();
1620 < //         await(locked2);
1621 <
1622 < //         lock.writeLock().lock();
1623 < //         assertTrue(lock.hasWaiters(c));
1624 < //         assertTrue(lock.getWaitingThreads(c).contains(t1));
1625 < //         assertTrue(lock.getWaitingThreads(c).contains(t2));
1626 < //         assertEquals(2, lock.getWaitingThreads(c).size());
1627 < //         c.signalAll();
1628 < //         assertHasNoWaiters(lock, c);
1629 < //         lock.writeLock().unlock();
1630 <
1631 < //         awaitTermination(t1);
1632 < //         awaitTermination(t2);
1633 <
1634 < //         assertHasNoWaiters(lock, c);
1635 < //     }
1636 <
1637 < //     /**
1638 < //      * toString indicates current lock state
1639 < //      */
1640 < //     public void testToString()      { testToString(false); }
1641 < //     public void testToString_fair() { testToString(true); }
1642 < //     public void testToString(boolean fair) {
1643 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1644 < //         assertTrue(lock.toString().contains("Write locks = 0"));
1645 < //         assertTrue(lock.toString().contains("Read locks = 0"));
1646 < //         lock.writeLock().lock();
1647 < //         assertTrue(lock.toString().contains("Write locks = 1"));
1648 < //         assertTrue(lock.toString().contains("Read locks = 0"));
1649 < //         lock.writeLock().unlock();
1650 < //         lock.readLock().lock();
1651 < //         lock.readLock().lock();
1652 < //         assertTrue(lock.toString().contains("Write locks = 0"));
1653 < //         assertTrue(lock.toString().contains("Read locks = 2"));
1654 < //     }
1655 <
1656 < //     /**
1657 < //      * readLock.toString indicates current lock state
1658 < //      */
1659 < //     public void testReadLockToString()      { testReadLockToString(false); }
1660 < //     public void testReadLockToString_fair() { testReadLockToString(true); }
1661 < //     public void testReadLockToString(boolean fair) {
1662 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1663 < //         assertTrue(lock.readLock().toString().contains("Read locks = 0"));
1664 < //         lock.readLock().lock();
1665 < //         lock.readLock().lock();
1666 < //         assertTrue(lock.readLock().toString().contains("Read locks = 2"));
1667 < //     }
1668 <
1669 < //     /**
1670 < //      * writeLock.toString indicates current lock state
1671 < //      */
1672 < //     public void testWriteLockToString()      { testWriteLockToString(false); }
1673 < //     public void testWriteLockToString_fair() { testWriteLockToString(true); }
1674 < //     public void testWriteLockToString(boolean fair) {
1675 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1676 < //         assertTrue(lock.writeLock().toString().contains("Unlocked"));
1677 < //         lock.writeLock().lock();
1678 < //         assertTrue(lock.writeLock().toString().contains("Locked"));
1679 < //         lock.writeLock().unlock();
1680 < //         assertTrue(lock.writeLock().toString().contains("Unlocked"));
1681 < //     }
42 >    /**
43 >     * Releases write lock, checking isWriteLocked before and after
44 >     */
45 >    void releaseWriteLock(StampedLock lock, long stamp) {
46 >        assertTrue(lock.isWriteLocked());
47 >        assertValid(lock, stamp);
48 >        lock.unlockWrite(stamp);
49 >        assertFalse(lock.isWriteLocked());
50 >        assertFalse(lock.validate(stamp));
51 >    }
52 >
53 >    /**
54 >     * Releases read lock, checking isReadLocked before and after
55 >     */
56 >    void releaseReadLock(StampedLock lock, long stamp) {
57 >        assertTrue(lock.isReadLocked());
58 >        assertValid(lock, stamp);
59 >        lock.unlockRead(stamp);
60 >        assertFalse(lock.isReadLocked());
61 >        assertTrue(lock.validate(stamp));
62 >    }
63 >
64 >    long assertNonZero(long v) {
65 >        assertTrue(v != 0L);
66 >        return v;
67 >    }
68 >
69 >    long assertValid(StampedLock lock, long stamp) {
70 >        assertTrue(stamp != 0L);
71 >        assertTrue(lock.validate(stamp));
72 >        return stamp;
73 >    }
74 >
75 >    void assertUnlocked(StampedLock lock) {
76 >        assertFalse(lock.isReadLocked());
77 >        assertFalse(lock.isWriteLocked());
78 >        assertEquals(0, lock.getReadLockCount());
79 >        assertValid(lock, lock.tryOptimisticRead());
80 >    }
81 >
82 >    List<Action> lockLockers(Lock lock) {
83 >        return List.of(
84 >            () -> lock.lock(),
85 >            () -> lock.lockInterruptibly(),
86 >            () -> lock.tryLock(),
87 >            () -> lock.tryLock(Long.MIN_VALUE, DAYS),
88 >            () -> lock.tryLock(0L, DAYS),
89 >            () -> lock.tryLock(Long.MAX_VALUE, DAYS));
90 >    }
91 >
92 >    List<Function<StampedLock, Long>> readLockers() {
93 >        return List.of(
94 >            sl -> sl.readLock(),
95 >            sl -> sl.tryReadLock(),
96 >            sl -> readLockInterruptiblyUninterrupted(sl),
97 >            sl -> tryReadLockUninterrupted(sl, Long.MIN_VALUE, DAYS),
98 >            sl -> tryReadLockUninterrupted(sl, 0L, DAYS),
99 >            sl -> sl.tryConvertToReadLock(sl.tryOptimisticRead()));
100 >    }
101 >
102 >    List<BiConsumer<StampedLock, Long>> readUnlockers() {
103 >        return List.of(
104 >            (sl, stamp) -> sl.unlockRead(stamp),
105 >            (sl, stamp) -> assertTrue(sl.tryUnlockRead()),
106 >            (sl, stamp) -> sl.asReadLock().unlock(),
107 >            (sl, stamp) -> sl.unlock(stamp),
108 >            (sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
109 >    }
110 >
111 >    List<Function<StampedLock, Long>> writeLockers() {
112 >        return List.of(
113 >            sl -> sl.writeLock(),
114 >            sl -> sl.tryWriteLock(),
115 >            sl -> writeLockInterruptiblyUninterrupted(sl),
116 >            sl -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS),
117 >            sl -> tryWriteLockUninterrupted(sl, 0L, DAYS),
118 >            sl -> sl.tryConvertToWriteLock(sl.tryOptimisticRead()));
119 >    }
120 >
121 >    List<BiConsumer<StampedLock, Long>> writeUnlockers() {
122 >        return List.of(
123 >            (sl, stamp) -> sl.unlockWrite(stamp),
124 >            (sl, stamp) -> assertTrue(sl.tryUnlockWrite()),
125 >            (sl, stamp) -> sl.asWriteLock().unlock(),
126 >            (sl, stamp) -> sl.unlock(stamp),
127 >            (sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
128 >    }
129 >
130 >    /**
131 >     * Constructed StampedLock is in unlocked state
132 >     */
133 >    public void testConstructor() {
134 >        assertUnlocked(new StampedLock());
135 >    }
136 >
137 >    /**
138 >     * write-locking, then unlocking, an unlocked lock succeed
139 >     */
140 >    public void testWriteLock_lockUnlock() {
141 >        StampedLock lock = new StampedLock();
142 >
143 >        for (Function<StampedLock, Long> writeLocker : writeLockers())
144 >        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
145 >            assertFalse(lock.isWriteLocked());
146 >            assertFalse(lock.isReadLocked());
147 >            assertEquals(0, lock.getReadLockCount());
148 >
149 >            long s = writeLocker.apply(lock);
150 >            assertValid(lock, s);
151 >            assertTrue(lock.isWriteLocked());
152 >            assertFalse(lock.isReadLocked());
153 >            assertEquals(0, lock.getReadLockCount());
154 >            writeUnlocker.accept(lock, s);
155 >            assertUnlocked(lock);
156 >        }
157 >    }
158 >
159 >    /**
160 >     * read-locking, then unlocking, an unlocked lock succeed
161 >     */
162 >    public void testReadLock_lockUnlock() {
163 >        StampedLock lock = new StampedLock();
164 >
165 >        for (Function<StampedLock, Long> readLocker : readLockers())
166 >        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
167 >            long s = 42;
168 >            for (int i = 0; i < 2; i++) {
169 >                s = assertValid(lock, readLocker.apply(lock));
170 >                assertFalse(lock.isWriteLocked());
171 >                assertTrue(lock.isReadLocked());
172 >                assertEquals(i + 1, lock.getReadLockCount());
173 >            }
174 >            for (int i = 0; i < 2; i++) {
175 >                assertFalse(lock.isWriteLocked());
176 >                assertTrue(lock.isReadLocked());
177 >                assertEquals(2 - i, lock.getReadLockCount());
178 >                readUnlocker.accept(lock, s);
179 >            }
180 >            assertUnlocked(lock);
181 >        }
182 >    }
183 >
184 >    /**
185 >     * tryUnlockWrite fails if not write locked
186 >     */
187 >    public void testTryUnlockWrite_failure() {
188 >        StampedLock lock = new StampedLock();
189 >        assertFalse(lock.tryUnlockWrite());
190 >
191 >        for (Function<StampedLock, Long> readLocker : readLockers())
192 >        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
193 >            long s = assertValid(lock, readLocker.apply(lock));
194 >            assertFalse(lock.tryUnlockWrite());
195 >            assertTrue(lock.isReadLocked());
196 >            readUnlocker.accept(lock, s);
197 >            assertUnlocked(lock);
198 >        }
199 >    }
200 >
201 >    /**
202 >     * tryUnlockRead fails if not read locked
203 >     */
204 >    public void testTryUnlockRead_failure() {
205 >        StampedLock lock = new StampedLock();
206 >        assertFalse(lock.tryUnlockRead());
207 >
208 >        for (Function<StampedLock, Long> writeLocker : writeLockers())
209 >        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
210 >            long s = writeLocker.apply(lock);
211 >            assertFalse(lock.tryUnlockRead());
212 >            assertTrue(lock.isWriteLocked());
213 >            writeUnlocker.accept(lock, s);
214 >            assertUnlocked(lock);
215 >        }
216 >    }
217 >
218 >    /**
219 >     * validate(0L) fails
220 >     */
221 >    public void testValidate0() {
222 >        StampedLock lock = new StampedLock();
223 >        assertFalse(lock.validate(0L));
224 >    }
225 >
226 >    /**
227 >     * A stamp obtained from a successful lock operation validates while the lock is held
228 >     */
229 >    public void testValidate() throws InterruptedException {
230 >        StampedLock lock = new StampedLock();
231 >
232 >        for (Function<StampedLock, Long> readLocker : readLockers())
233 >        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
234 >            long s = assertNonZero(readLocker.apply(lock));
235 >            assertTrue(lock.validate(s));
236 >            readUnlocker.accept(lock, s);
237 >        }
238 >
239 >        for (Function<StampedLock, Long> writeLocker : writeLockers())
240 >        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
241 >            long s = assertNonZero(writeLocker.apply(lock));
242 >            assertTrue(lock.validate(s));
243 >            writeUnlocker.accept(lock, s);
244 >        }
245 >    }
246 >
247 >    /**
248 >     * A stamp obtained from an unsuccessful lock operation does not validate
249 >     */
250 >    public void testValidate2() throws InterruptedException {
251 >        StampedLock lock = new StampedLock();
252 >        long s = assertNonZero(lock.writeLock());
253 >        assertTrue(lock.validate(s));
254 >        assertFalse(lock.validate(lock.tryWriteLock()));
255 >        assertFalse(lock.validate(lock.tryWriteLock(randomExpiredTimeout(),
256 >                                                    randomTimeUnit())));
257 >        assertFalse(lock.validate(lock.tryReadLock()));
258 >        assertFalse(lock.validate(lock.tryWriteLock(randomExpiredTimeout(),
259 >                                                    randomTimeUnit())));
260 >        assertFalse(lock.validate(lock.tryOptimisticRead()));
261 >        lock.unlockWrite(s);
262 >    }
263 >
264 >    void assertThrowInterruptedExceptionWhenPreInterrupted(Action[] actions) {
265 >        for (Action action : actions) {
266 >            Thread.currentThread().interrupt();
267 >            try {
268 >                action.run();
269 >                shouldThrow();
270 >            }
271 >            catch (InterruptedException success) {}
272 >            catch (Throwable fail) { threadUnexpectedException(fail); }
273 >            assertFalse(Thread.interrupted());
274 >        }
275 >    }
276 >
277 >    /**
278 >     * interruptible operations throw InterruptedException when pre-interrupted
279 >     */
280 >    public void testInterruptibleOperationsThrowInterruptedExceptionWhenPreInterrupted() {
281 >        final StampedLock lock = new StampedLock();
282 >
283 >        Action[] interruptibleLockActions = {
284 >            () -> lock.writeLockInterruptibly(),
285 >            () -> lock.tryWriteLock(Long.MIN_VALUE, DAYS),
286 >            () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
287 >            () -> lock.readLockInterruptibly(),
288 >            () -> lock.tryReadLock(Long.MIN_VALUE, DAYS),
289 >            () -> lock.tryReadLock(Long.MAX_VALUE, DAYS),
290 >            () -> lock.asWriteLock().lockInterruptibly(),
291 >            () -> lock.asWriteLock().tryLock(0L, DAYS),
292 >            () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
293 >            () -> lock.asReadLock().lockInterruptibly(),
294 >            () -> lock.asReadLock().tryLock(0L, DAYS),
295 >            () -> lock.asReadLock().tryLock(Long.MAX_VALUE, DAYS),
296 >        };
297 >        shuffle(interruptibleLockActions);
298 >
299 >        assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
300 >        {
301 >            long s = lock.writeLock();
302 >            assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
303 >            lock.unlockWrite(s);
304 >        }
305 >        {
306 >            long s = lock.readLock();
307 >            assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
308 >            lock.unlockRead(s);
309 >        }
310 >    }
311 >
312 >    void assertThrowInterruptedExceptionWhenInterrupted(Action[] actions) {
313 >        int n = actions.length;
314 >        Future<?>[] futures = new Future<?>[n];
315 >        CountDownLatch threadsStarted = new CountDownLatch(n);
316 >        CountDownLatch done = new CountDownLatch(n);
317 >
318 >        for (int i = 0; i < n; i++) {
319 >            Action action = actions[i];
320 >            futures[i] = cachedThreadPool.submit(new CheckedRunnable() {
321 >                public void realRun() throws Throwable {
322 >                    threadsStarted.countDown();
323 >                    try {
324 >                        action.run();
325 >                        shouldThrow();
326 >                    }
327 >                    catch (InterruptedException success) {}
328 >                    catch (Throwable fail) { threadUnexpectedException(fail); }
329 >                    assertFalse(Thread.interrupted());
330 >                    done.countDown();
331 >                }});
332 >        }
333 >
334 >        await(threadsStarted);
335 >        assertEquals(n, done.getCount());
336 >        for (Future<?> future : futures) // Interrupt all the tasks
337 >            future.cancel(true);
338 >        await(done);
339 >    }
340 >
341 >    /**
342 >     * interruptible operations throw InterruptedException when write locked and interrupted
343 >     */
344 >    public void testInterruptibleOperationsThrowInterruptedExceptionWriteLockedInterrupted() {
345 >        final StampedLock lock = new StampedLock();
346 >        long stamp = lock.writeLock();
347 >
348 >        Action[] interruptibleLockBlockingActions = {
349 >            () -> lock.writeLockInterruptibly(),
350 >            () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
351 >            () -> lock.readLockInterruptibly(),
352 >            () -> lock.tryReadLock(Long.MAX_VALUE, DAYS),
353 >            () -> lock.asWriteLock().lockInterruptibly(),
354 >            () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
355 >            () -> lock.asReadLock().lockInterruptibly(),
356 >            () -> lock.asReadLock().tryLock(Long.MAX_VALUE, DAYS),
357 >        };
358 >        shuffle(interruptibleLockBlockingActions);
359 >
360 >        assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions);
361 >
362 >        releaseWriteLock(lock, stamp);
363 >    }
364 >
365 >    /**
366 >     * interruptible operations throw InterruptedException when read locked and interrupted
367 >     */
368 >    public void testInterruptibleOperationsThrowInterruptedExceptionReadLockedInterrupted() {
369 >        final StampedLock lock = new StampedLock();
370 >        long stamp = lock.readLock();
371 >
372 >        Action[] interruptibleLockBlockingActions = {
373 >            () -> lock.writeLockInterruptibly(),
374 >            () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
375 >            () -> lock.asWriteLock().lockInterruptibly(),
376 >            () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
377 >        };
378 >        shuffle(interruptibleLockBlockingActions);
379 >
380 >        assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions);
381 >
382 >        releaseReadLock(lock, stamp);
383 >    }
384 >
385 >    /**
386 >     * Non-interruptible operations ignore and preserve interrupt status
387 >     */
388 >    public void testNonInterruptibleOperationsIgnoreInterrupts() {
389 >        final StampedLock lock = new StampedLock();
390 >        Thread.currentThread().interrupt();
391 >
392 >        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
393 >            long s = assertValid(lock, lock.readLock());
394 >            readUnlocker.accept(lock, s);
395 >            s = assertValid(lock, lock.tryReadLock());
396 >            readUnlocker.accept(lock, s);
397 >        }
398 >
399 >        lock.asReadLock().lock();
400 >        lock.asReadLock().unlock();
401 >
402 >        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
403 >            long s = assertValid(lock, lock.writeLock());
404 >            writeUnlocker.accept(lock, s);
405 >            s = assertValid(lock, lock.tryWriteLock());
406 >            writeUnlocker.accept(lock, s);
407 >        }
408 >
409 >        lock.asWriteLock().lock();
410 >        lock.asWriteLock().unlock();
411 >
412 >        assertTrue(Thread.interrupted());
413 >    }
414 >
415 >    /**
416 >     * tryWriteLock on an unlocked lock succeeds
417 >     */
418 >    public void testTryWriteLock() {
419 >        final StampedLock lock = new StampedLock();
420 >        long s = lock.tryWriteLock();
421 >        assertTrue(s != 0L);
422 >        assertTrue(lock.isWriteLocked());
423 >        assertEquals(0L, lock.tryWriteLock());
424 >        releaseWriteLock(lock, s);
425 >    }
426 >
427 >    /**
428 >     * tryWriteLock fails if locked
429 >     */
430 >    public void testTryWriteLockWhenLocked() {
431 >        final StampedLock lock = new StampedLock();
432 >        long s = lock.writeLock();
433 >        Thread t = newStartedThread(new CheckedRunnable() {
434 >            public void realRun() {
435 >                assertEquals(0L, lock.tryWriteLock());
436 >            }});
437 >
438 >        assertEquals(0L, lock.tryWriteLock());
439 >        awaitTermination(t);
440 >        releaseWriteLock(lock, s);
441 >    }
442 >
443 >    /**
444 >     * tryReadLock fails if write-locked
445 >     */
446 >    public void testTryReadLockWhenLocked() {
447 >        final StampedLock lock = new StampedLock();
448 >        long s = lock.writeLock();
449 >        Thread t = newStartedThread(new CheckedRunnable() {
450 >            public void realRun() {
451 >                assertEquals(0L, lock.tryReadLock());
452 >            }});
453 >
454 >        assertEquals(0L, lock.tryReadLock());
455 >        awaitTermination(t);
456 >        releaseWriteLock(lock, s);
457 >    }
458 >
459 >    /**
460 >     * Multiple threads can hold a read lock when not write-locked
461 >     */
462 >    public void testMultipleReadLocks() {
463 >        final StampedLock lock = new StampedLock();
464 >        final long s = lock.readLock();
465 >        Thread t = newStartedThread(new CheckedRunnable() {
466 >            public void realRun() throws InterruptedException {
467 >                long s2 = lock.tryReadLock();
468 >                assertValid(lock, s2);
469 >                lock.unlockRead(s2);
470 >                long s3 = lock.tryReadLock(LONG_DELAY_MS, MILLISECONDS);
471 >                assertValid(lock, s3);
472 >                lock.unlockRead(s3);
473 >                long s4 = lock.readLock();
474 >                assertValid(lock, s4);
475 >                lock.unlockRead(s4);
476 >                lock.asReadLock().lock();
477 >                lock.asReadLock().unlock();
478 >                lock.asReadLock().lockInterruptibly();
479 >                lock.asReadLock().unlock();
480 >                lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS);
481 >                lock.asReadLock().unlock();
482 >            }});
483 >
484 >        awaitTermination(t);
485 >        lock.unlockRead(s);
486 >    }
487 >
488 >    /**
489 >     * writeLock() succeeds only after a reading thread unlocks
490 >     */
491 >    public void testWriteAfterReadLock() throws InterruptedException {
492 >        final CountDownLatch aboutToLock = new CountDownLatch(1);
493 >        final StampedLock lock = new StampedLock();
494 >        long rs = lock.readLock();
495 >        Thread t = newStartedThread(new CheckedRunnable() {
496 >            public void realRun() {
497 >                aboutToLock.countDown();
498 >                long s = lock.writeLock();
499 >                assertTrue(lock.isWriteLocked());
500 >                assertFalse(lock.isReadLocked());
501 >                lock.unlockWrite(s);
502 >            }});
503 >
504 >        await(aboutToLock);
505 >        assertThreadBlocks(t, Thread.State.WAITING);
506 >        assertFalse(lock.isWriteLocked());
507 >        assertTrue(lock.isReadLocked());
508 >        lock.unlockRead(rs);
509 >        awaitTermination(t);
510 >        assertUnlocked(lock);
511 >    }
512 >
513 >    /**
514 >     * writeLock() succeeds only after reading threads unlock
515 >     */
516 >    public void testWriteAfterMultipleReadLocks() {
517 >        final StampedLock lock = new StampedLock();
518 >        long s = lock.readLock();
519 >        Thread t1 = newStartedThread(new CheckedRunnable() {
520 >            public void realRun() {
521 >                long rs = lock.readLock();
522 >                lock.unlockRead(rs);
523 >            }});
524 >
525 >        awaitTermination(t1);
526 >
527 >        Thread t2 = newStartedThread(new CheckedRunnable() {
528 >            public void realRun() {
529 >                long ws = lock.writeLock();
530 >                lock.unlockWrite(ws);
531 >            }});
532 >
533 >        assertTrue(lock.isReadLocked());
534 >        assertFalse(lock.isWriteLocked());
535 >        lock.unlockRead(s);
536 >        awaitTermination(t2);
537 >        assertUnlocked(lock);
538 >    }
539 >
540 >    /**
541 >     * readLock() succeed only after a writing thread unlocks
542 >     */
543 >    public void testReadAfterWriteLock() {
544 >        final StampedLock lock = new StampedLock();
545 >        final CountDownLatch threadsStarted = new CountDownLatch(2);
546 >        final long s = lock.writeLock();
547 >        final Runnable acquireReleaseReadLock = new CheckedRunnable() {
548 >            public void realRun() {
549 >                threadsStarted.countDown();
550 >                long rs = lock.readLock();
551 >                assertTrue(lock.isReadLocked());
552 >                assertFalse(lock.isWriteLocked());
553 >                lock.unlockRead(rs);
554 >            }};
555 >        Thread t1 = newStartedThread(acquireReleaseReadLock);
556 >        Thread t2 = newStartedThread(acquireReleaseReadLock);
557 >
558 >        await(threadsStarted);
559 >        assertThreadBlocks(t1, Thread.State.WAITING);
560 >        assertThreadBlocks(t2, Thread.State.WAITING);
561 >        assertTrue(lock.isWriteLocked());
562 >        assertFalse(lock.isReadLocked());
563 >        releaseWriteLock(lock, s);
564 >        awaitTermination(t1);
565 >        awaitTermination(t2);
566 >        assertUnlocked(lock);
567 >    }
568 >
569 >    /**
570 >     * tryReadLock succeeds if read locked but not write locked
571 >     */
572 >    public void testTryLockWhenReadLocked() {
573 >        final StampedLock lock = new StampedLock();
574 >        long s = lock.readLock();
575 >        Thread t = newStartedThread(new CheckedRunnable() {
576 >            public void realRun() {
577 >                long rs = lock.tryReadLock();
578 >                assertValid(lock, rs);
579 >                lock.unlockRead(rs);
580 >            }});
581 >
582 >        awaitTermination(t);
583 >        lock.unlockRead(s);
584 >    }
585 >
586 >    /**
587 >     * tryWriteLock fails when read locked
588 >     */
589 >    public void testTryWriteLockWhenReadLocked() {
590 >        final StampedLock lock = new StampedLock();
591 >        long s = lock.readLock();
592 >        Thread t = newStartedThread(new CheckedRunnable() {
593 >            public void realRun() {
594 >                assertEquals(0L, lock.tryWriteLock());
595 >            }});
596 >
597 >        awaitTermination(t);
598 >        lock.unlockRead(s);
599 >    }
600 >
601 >    /**
602 >     * timed lock operations time out if lock not available
603 >     */
604 >    public void testTimedLock_Timeout() throws Exception {
605 >        ArrayList<Future<?>> futures = new ArrayList<>();
606 >
607 >        // Write locked
608 >        final StampedLock lock = new StampedLock();
609 >        long stamp = lock.writeLock();
610 >        assertEquals(0L, lock.tryReadLock(0L, DAYS));
611 >        assertEquals(0L, lock.tryReadLock(Long.MIN_VALUE, DAYS));
612 >        assertFalse(lock.asReadLock().tryLock(0L, DAYS));
613 >        assertFalse(lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS));
614 >        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
615 >        assertEquals(0L, lock.tryWriteLock(Long.MIN_VALUE, DAYS));
616 >        assertFalse(lock.asWriteLock().tryLock(0L, DAYS));
617 >        assertFalse(lock.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
618 >
619 >        futures.add(cachedThreadPool.submit(new CheckedRunnable() {
620 >            public void realRun() throws InterruptedException {
621 >                long startTime = System.nanoTime();
622 >                assertEquals(0L, lock.tryWriteLock(timeoutMillis(), MILLISECONDS));
623 >                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
624 >            }}));
625 >
626 >        futures.add(cachedThreadPool.submit(new CheckedRunnable() {
627 >            public void realRun() throws InterruptedException {
628 >                long startTime = System.nanoTime();
629 >                assertEquals(0L, lock.tryReadLock(timeoutMillis(), MILLISECONDS));
630 >                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
631 >            }}));
632 >
633 >        // Read locked
634 >        final StampedLock lock2 = new StampedLock();
635 >        long stamp2 = lock2.readLock();
636 >        assertEquals(0L, lock2.tryWriteLock(0L, DAYS));
637 >        assertEquals(0L, lock2.tryWriteLock(Long.MIN_VALUE, DAYS));
638 >        assertFalse(lock2.asWriteLock().tryLock(0L, DAYS));
639 >        assertFalse(lock2.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
640 >
641 >        futures.add(cachedThreadPool.submit(new CheckedRunnable() {
642 >            public void realRun() throws InterruptedException {
643 >                long startTime = System.nanoTime();
644 >                assertEquals(0L, lock2.tryWriteLock(timeoutMillis(), MILLISECONDS));
645 >                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
646 >            }}));
647 >
648 >        for (Future<?> future : futures)
649 >            assertNull(future.get());
650 >
651 >        releaseWriteLock(lock, stamp);
652 >        releaseReadLock(lock2, stamp2);
653 >    }
654 >
655 >    /**
656 >     * writeLockInterruptibly succeeds if unlocked
657 >     */
658 >    public void testWriteLockInterruptibly() throws InterruptedException {
659 >        final StampedLock lock = new StampedLock();
660 >        long s = lock.writeLockInterruptibly();
661 >        assertTrue(lock.isWriteLocked());
662 >        releaseWriteLock(lock, s);
663 >    }
664 >
665 >    /**
666 >     * readLockInterruptibly succeeds if lock free
667 >     */
668 >    public void testReadLockInterruptibly() throws InterruptedException {
669 >        final StampedLock lock = new StampedLock();
670 >
671 >        long s = assertValid(lock, lock.readLockInterruptibly());
672 >        assertTrue(lock.isReadLocked());
673 >        lock.unlockRead(s);
674 >
675 >        lock.asReadLock().lockInterruptibly();
676 >        assertTrue(lock.isReadLocked());
677 >        lock.asReadLock().unlock();
678 >    }
679 >
680 >    /**
681 >     * A serialized lock deserializes as unlocked
682 >     */
683 >    public void testSerialization() {
684 >        StampedLock lock = new StampedLock();
685 >        lock.writeLock();
686 >        StampedLock clone = serialClone(lock);
687 >        assertTrue(lock.isWriteLocked());
688 >        assertFalse(clone.isWriteLocked());
689 >        long s = clone.writeLock();
690 >        assertTrue(clone.isWriteLocked());
691 >        clone.unlockWrite(s);
692 >        assertFalse(clone.isWriteLocked());
693 >    }
694 >
695 >    /**
696 >     * toString indicates current lock state
697 >     */
698 >    public void testToString() {
699 >        StampedLock lock = new StampedLock();
700 >        assertTrue(lock.toString().contains("Unlocked"));
701 >        long s = lock.writeLock();
702 >        assertTrue(lock.toString().contains("Write-locked"));
703 >        lock.unlockWrite(s);
704 >        s = lock.readLock();
705 >        assertTrue(lock.toString().contains("Read-locks"));
706 >        releaseReadLock(lock, s);
707 >    }
708 >
709 >    /**
710 >     * tryOptimisticRead succeeds and validates if unlocked, fails if
711 >     * exclusively locked
712 >     */
713 >    public void testValidateOptimistic() throws InterruptedException {
714 >        StampedLock lock = new StampedLock();
715 >
716 >        assertValid(lock, lock.tryOptimisticRead());
717 >
718 >        for (Function<StampedLock, Long> writeLocker : writeLockers()) {
719 >            long s = assertValid(lock, writeLocker.apply(lock));
720 >            assertEquals(0L, lock.tryOptimisticRead());
721 >            releaseWriteLock(lock, s);
722 >        }
723 >
724 >        for (Function<StampedLock, Long> readLocker : readLockers()) {
725 >            long s = assertValid(lock, readLocker.apply(lock));
726 >            long p = assertValid(lock, lock.tryOptimisticRead());
727 >            releaseReadLock(lock, s);
728 >            assertTrue(lock.validate(p));
729 >        }
730 >
731 >        assertValid(lock, lock.tryOptimisticRead());
732 >    }
733 >
734 >    /**
735 >     * tryOptimisticRead stamp does not validate if a write lock intervenes
736 >     */
737 >    public void testValidateOptimisticWriteLocked() {
738 >        final StampedLock lock = new StampedLock();
739 >        final long p = assertValid(lock, lock.tryOptimisticRead());
740 >        final long s = assertValid(lock, lock.writeLock());
741 >        assertFalse(lock.validate(p));
742 >        assertEquals(0L, lock.tryOptimisticRead());
743 >        assertTrue(lock.validate(s));
744 >        lock.unlockWrite(s);
745 >    }
746 >
747 >    /**
748 >     * tryOptimisticRead stamp does not validate if a write lock
749 >     * intervenes in another thread
750 >     */
751 >    public void testValidateOptimisticWriteLocked2()
752 >            throws InterruptedException {
753 >        final CountDownLatch locked = new CountDownLatch(1);
754 >        final StampedLock lock = new StampedLock();
755 >        final long p = assertValid(lock, lock.tryOptimisticRead());
756 >
757 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
758 >            public void realRun() throws InterruptedException {
759 >                lock.writeLockInterruptibly();
760 >                locked.countDown();
761 >                lock.writeLockInterruptibly();
762 >            }});
763 >
764 >        await(locked);
765 >        assertFalse(lock.validate(p));
766 >        assertEquals(0L, lock.tryOptimisticRead());
767 >        assertThreadBlocks(t, Thread.State.WAITING);
768 >        t.interrupt();
769 >        awaitTermination(t);
770 >        assertTrue(lock.isWriteLocked());
771 >    }
772 >
773 >    /**
774 >     * tryConvertToOptimisticRead succeeds and validates if successfully locked
775 >     */
776 >    public void testTryConvertToOptimisticRead() throws InterruptedException {
777 >        StampedLock lock = new StampedLock();
778 >        long s, p, q;
779 >        assertEquals(0L, lock.tryConvertToOptimisticRead(0L));
780 >
781 >        s = assertValid(lock, lock.tryOptimisticRead());
782 >        assertEquals(s, lock.tryConvertToOptimisticRead(s));
783 >        assertTrue(lock.validate(s));
784 >
785 >        for (Function<StampedLock, Long> writeLocker : writeLockers()) {
786 >            s = assertValid(lock, writeLocker.apply(lock));
787 >            p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
788 >            assertFalse(lock.validate(s));
789 >            assertTrue(lock.validate(p));
790 >            assertUnlocked(lock);
791 >        }
792 >
793 >        for (Function<StampedLock, Long> readLocker : readLockers()) {
794 >            s = assertValid(lock, readLocker.apply(lock));
795 >            q = assertValid(lock, lock.tryOptimisticRead());
796 >            assertEquals(q, lock.tryConvertToOptimisticRead(q));
797 >            assertTrue(lock.validate(q));
798 >            assertTrue(lock.isReadLocked());
799 >            p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
800 >            assertTrue(lock.validate(p));
801 >            assertTrue(lock.validate(s));
802 >            assertUnlocked(lock);
803 >            assertEquals(q, lock.tryConvertToOptimisticRead(q));
804 >            assertTrue(lock.validate(q));
805 >        }
806 >    }
807 >
808 >    /**
809 >     * tryConvertToReadLock succeeds for valid stamps
810 >     */
811 >    public void testTryConvertToReadLock() throws InterruptedException {
812 >        StampedLock lock = new StampedLock();
813 >        long s, p;
814 >
815 >        assertEquals(0L, lock.tryConvertToReadLock(0L));
816 >
817 >        s = assertValid(lock, lock.tryOptimisticRead());
818 >        p = assertValid(lock, lock.tryConvertToReadLock(s));
819 >        assertTrue(lock.isReadLocked());
820 >        assertEquals(1, lock.getReadLockCount());
821 >        assertTrue(lock.validate(s));
822 >        lock.unlockRead(p);
823 >
824 >        s = assertValid(lock, lock.tryOptimisticRead());
825 >        lock.readLock();
826 >        p = assertValid(lock, lock.tryConvertToReadLock(s));
827 >        assertTrue(lock.isReadLocked());
828 >        assertEquals(2, lock.getReadLockCount());
829 >        lock.unlockRead(p);
830 >        lock.unlockRead(p);
831 >        assertUnlocked(lock);
832 >
833 >        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
834 >            for (Function<StampedLock, Long> writeLocker : writeLockers()) {
835 >                s = assertValid(lock, writeLocker.apply(lock));
836 >                p = assertValid(lock, lock.tryConvertToReadLock(s));
837 >                assertFalse(lock.validate(s));
838 >                assertTrue(lock.isReadLocked());
839 >                assertEquals(1, lock.getReadLockCount());
840 >                readUnlocker.accept(lock, p);
841 >            }
842 >
843 >            for (Function<StampedLock, Long> readLocker : readLockers()) {
844 >                s = assertValid(lock, readLocker.apply(lock));
845 >                assertEquals(s, lock.tryConvertToReadLock(s));
846 >                assertTrue(lock.validate(s));
847 >                assertTrue(lock.isReadLocked());
848 >                assertEquals(1, lock.getReadLockCount());
849 >                readUnlocker.accept(lock, s);
850 >            }
851 >        }
852 >    }
853 >
854 >    /**
855 >     * tryConvertToWriteLock succeeds if lock available; fails if multiply read locked
856 >     */
857 >    public void testTryConvertToWriteLock() throws InterruptedException {
858 >        StampedLock lock = new StampedLock();
859 >        long s, p;
860 >
861 >        assertEquals(0L, lock.tryConvertToWriteLock(0L));
862 >
863 >        assertTrue((s = lock.tryOptimisticRead()) != 0L);
864 >        assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
865 >        assertTrue(lock.isWriteLocked());
866 >        lock.unlockWrite(p);
867 >
868 >        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
869 >            for (Function<StampedLock, Long> writeLocker : writeLockers()) {
870 >                s = assertValid(lock, writeLocker.apply(lock));
871 >                assertEquals(s, lock.tryConvertToWriteLock(s));
872 >                assertTrue(lock.validate(s));
873 >                assertTrue(lock.isWriteLocked());
874 >                writeUnlocker.accept(lock, s);
875 >            }
876 >
877 >            for (Function<StampedLock, Long> readLocker : readLockers()) {
878 >                s = assertValid(lock, readLocker.apply(lock));
879 >                p = assertValid(lock, lock.tryConvertToWriteLock(s));
880 >                assertFalse(lock.validate(s));
881 >                assertTrue(lock.validate(p));
882 >                assertTrue(lock.isWriteLocked());
883 >                writeUnlocker.accept(lock, p);
884 >            }
885 >        }
886 >
887 >        // failure if multiply read locked
888 >        for (Function<StampedLock, Long> readLocker : readLockers()) {
889 >            s = assertValid(lock, readLocker.apply(lock));
890 >            p = assertValid(lock, readLocker.apply(lock));
891 >            assertEquals(0L, lock.tryConvertToWriteLock(s));
892 >            assertTrue(lock.validate(s));
893 >            assertTrue(lock.validate(p));
894 >            assertEquals(2, lock.getReadLockCount());
895 >            lock.unlock(p);
896 >            lock.unlock(s);
897 >            assertUnlocked(lock);
898 >        }
899 >    }
900 >
901 >    /**
902 >     * asWriteLock can be locked and unlocked
903 >     */
904 >    public void testAsWriteLock() throws Throwable {
905 >        StampedLock sl = new StampedLock();
906 >        Lock lock = sl.asWriteLock();
907 >        for (Action locker : lockLockers(lock)) {
908 >            locker.run();
909 >            assertTrue(sl.isWriteLocked());
910 >            assertFalse(sl.isReadLocked());
911 >            assertFalse(lock.tryLock());
912 >            lock.unlock();
913 >            assertUnlocked(sl);
914 >        }
915 >    }
916 >
917 >    /**
918 >     * asReadLock can be locked and unlocked
919 >     */
920 >    public void testAsReadLock() throws Throwable {
921 >        StampedLock sl = new StampedLock();
922 >        Lock lock = sl.asReadLock();
923 >        for (Action locker : lockLockers(lock)) {
924 >            locker.run();
925 >            assertTrue(sl.isReadLocked());
926 >            assertFalse(sl.isWriteLocked());
927 >            assertEquals(1, sl.getReadLockCount());
928 >            locker.run();
929 >            assertTrue(sl.isReadLocked());
930 >            assertEquals(2, sl.getReadLockCount());
931 >            lock.unlock();
932 >            lock.unlock();
933 >            assertUnlocked(sl);
934 >        }
935 >    }
936 >
937 >    /**
938 >     * asReadWriteLock.writeLock can be locked and unlocked
939 >     */
940 >    public void testAsReadWriteLockWriteLock() throws Throwable {
941 >        StampedLock sl = new StampedLock();
942 >        Lock lock = sl.asReadWriteLock().writeLock();
943 >        for (Action locker : lockLockers(lock)) {
944 >            locker.run();
945 >            assertTrue(sl.isWriteLocked());
946 >            assertFalse(sl.isReadLocked());
947 >            assertFalse(lock.tryLock());
948 >            lock.unlock();
949 >            assertUnlocked(sl);
950 >        }
951 >    }
952 >
953 >    /**
954 >     * asReadWriteLock.readLock can be locked and unlocked
955 >     */
956 >    public void testAsReadWriteLockReadLock() throws Throwable {
957 >        StampedLock sl = new StampedLock();
958 >        Lock lock = sl.asReadWriteLock().readLock();
959 >        for (Action locker : lockLockers(lock)) {
960 >            locker.run();
961 >            assertTrue(sl.isReadLocked());
962 >            assertFalse(sl.isWriteLocked());
963 >            assertEquals(1, sl.getReadLockCount());
964 >            locker.run();
965 >            assertTrue(sl.isReadLocked());
966 >            assertEquals(2, sl.getReadLockCount());
967 >            lock.unlock();
968 >            lock.unlock();
969 >            assertUnlocked(sl);
970 >        }
971 >    }
972 >
973 >    /**
974 >     * Lock.newCondition throws UnsupportedOperationException
975 >     */
976 >    public void testLockViewsDoNotSupportConditions() {
977 >        StampedLock sl = new StampedLock();
978 >        assertThrows(UnsupportedOperationException.class,
979 >                     () -> sl.asWriteLock().newCondition(),
980 >                     () -> sl.asReadLock().newCondition(),
981 >                     () -> sl.asReadWriteLock().writeLock().newCondition(),
982 >                     () -> sl.asReadWriteLock().readLock().newCondition());
983 >    }
984 >
985 >    /**
986 >     * Passing optimistic read stamps to unlock operations result in
987 >     * IllegalMonitorStateException
988 >     */
989 >    public void testCannotUnlockOptimisticReadStamps() {
990 >        {
991 >            StampedLock sl = new StampedLock();
992 >            long stamp = assertValid(sl, sl.tryOptimisticRead());
993 >            assertThrows(IllegalMonitorStateException.class,
994 >                () -> sl.unlockRead(stamp));
995 >        }
996 >        {
997 >            StampedLock sl = new StampedLock();
998 >            long stamp = sl.tryOptimisticRead();
999 >            assertThrows(IllegalMonitorStateException.class,
1000 >                () -> sl.unlock(stamp));
1001 >        }
1002 >
1003 >        {
1004 >            StampedLock sl = new StampedLock();
1005 >            long stamp = sl.tryOptimisticRead();
1006 >            sl.writeLock();
1007 >            assertThrows(IllegalMonitorStateException.class,
1008 >                () -> sl.unlock(stamp));
1009 >        }
1010 >        {
1011 >            StampedLock sl = new StampedLock();
1012 >            sl.readLock();
1013 >            long stamp = assertValid(sl, sl.tryOptimisticRead());
1014 >            assertThrows(IllegalMonitorStateException.class,
1015 >                () -> sl.unlockRead(stamp));
1016 >        }
1017 >        {
1018 >            StampedLock sl = new StampedLock();
1019 >            sl.readLock();
1020 >            long stamp = assertValid(sl, sl.tryOptimisticRead());
1021 >            assertThrows(IllegalMonitorStateException.class,
1022 >                () -> sl.unlock(stamp));
1023 >        }
1024 >
1025 >        {
1026 >            StampedLock sl = new StampedLock();
1027 >            long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1028 >            assertValid(sl, stamp);
1029 >            sl.writeLock();
1030 >            assertThrows(IllegalMonitorStateException.class,
1031 >                () -> sl.unlockWrite(stamp));
1032 >        }
1033 >        {
1034 >            StampedLock sl = new StampedLock();
1035 >            long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1036 >            sl.writeLock();
1037 >            assertThrows(IllegalMonitorStateException.class,
1038 >                () -> sl.unlock(stamp));
1039 >        }
1040 >        {
1041 >            StampedLock sl = new StampedLock();
1042 >            long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1043 >            sl.readLock();
1044 >            assertThrows(IllegalMonitorStateException.class,
1045 >                () -> sl.unlockRead(stamp));
1046 >        }
1047 >        {
1048 >            StampedLock sl = new StampedLock();
1049 >            long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1050 >            sl.readLock();
1051 >            assertThrows(IllegalMonitorStateException.class,
1052 >                () -> sl.unlock(stamp));
1053 >        }
1054 >
1055 >        {
1056 >            StampedLock sl = new StampedLock();
1057 >            long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1058 >            assertValid(sl, stamp);
1059 >            sl.writeLock();
1060 >            assertThrows(IllegalMonitorStateException.class,
1061 >                () -> sl.unlockWrite(stamp));
1062 >            }
1063 >        {
1064 >            StampedLock sl = new StampedLock();
1065 >            long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1066 >            sl.writeLock();
1067 >            assertThrows(IllegalMonitorStateException.class,
1068 >                () -> sl.unlock(stamp));
1069 >        }
1070 >        {
1071 >            StampedLock sl = new StampedLock();
1072 >            long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1073 >            sl.readLock();
1074 >            assertThrows(IllegalMonitorStateException.class,
1075 >                () -> sl.unlockRead(stamp));
1076 >        }
1077 >        {
1078 >            StampedLock sl = new StampedLock();
1079 >            sl.readLock();
1080 >            long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1081 >            assertValid(sl, stamp);
1082 >            sl.readLock();
1083 >            assertThrows(IllegalMonitorStateException.class,
1084 >                () -> sl.unlockRead(stamp));
1085 >        }
1086 >        {
1087 >            StampedLock sl = new StampedLock();
1088 >            long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1089 >            sl.readLock();
1090 >            assertThrows(IllegalMonitorStateException.class,
1091 >                () -> sl.unlock(stamp));
1092 >        }
1093 >        {
1094 >            StampedLock sl = new StampedLock();
1095 >            sl.readLock();
1096 >            long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1097 >            sl.readLock();
1098 >            assertThrows(IllegalMonitorStateException.class,
1099 >                () -> sl.unlock(stamp));
1100 >        }
1101 >    }
1102 >
1103 >    static long writeLockInterruptiblyUninterrupted(StampedLock sl) {
1104 >        try { return sl.writeLockInterruptibly(); }
1105 >        catch (InterruptedException ex) { throw new AssertionError(ex); }
1106 >    }
1107 >
1108 >    static long tryWriteLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1109 >        try { return sl.tryWriteLock(time, unit); }
1110 >        catch (InterruptedException ex) { throw new AssertionError(ex); }
1111 >    }
1112 >
1113 >    static long readLockInterruptiblyUninterrupted(StampedLock sl) {
1114 >        try { return sl.readLockInterruptibly(); }
1115 >        catch (InterruptedException ex) { throw new AssertionError(ex); }
1116 >    }
1117 >
1118 >    static long tryReadLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1119 >        try { return sl.tryReadLock(time, unit); }
1120 >        catch (InterruptedException ex) { throw new AssertionError(ex); }
1121 >    }
1122 >
1123 >    /**
1124 >     * Invalid stamps result in IllegalMonitorStateException
1125 >     */
1126 >    public void testInvalidStampsThrowIllegalMonitorStateException() {
1127 >        final StampedLock sl = new StampedLock();
1128 >
1129 >        assertThrows(IllegalMonitorStateException.class,
1130 >                     () -> sl.unlockWrite(0L),
1131 >                     () -> sl.unlockRead(0L),
1132 >                     () -> sl.unlock(0L));
1133 >
1134 >        final long optimisticStamp = sl.tryOptimisticRead();
1135 >        final long readStamp = sl.readLock();
1136 >        sl.unlockRead(readStamp);
1137 >        final long writeStamp = sl.writeLock();
1138 >        sl.unlockWrite(writeStamp);
1139 >        assertTrue(optimisticStamp != 0L && readStamp != 0L && writeStamp != 0L);
1140 >        final long[] noLongerValidStamps = { optimisticStamp, readStamp, writeStamp };
1141 >        final Runnable assertNoLongerValidStampsThrow = () -> {
1142 >            for (long noLongerValidStamp : noLongerValidStamps)
1143 >                assertThrows(IllegalMonitorStateException.class,
1144 >                             () -> sl.unlockWrite(noLongerValidStamp),
1145 >                             () -> sl.unlockRead(noLongerValidStamp),
1146 >                             () -> sl.unlock(noLongerValidStamp));
1147 >        };
1148 >        assertNoLongerValidStampsThrow.run();
1149 >
1150 >        for (Function<StampedLock, Long> readLocker : readLockers())
1151 >        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
1152 >            final long stamp = readLocker.apply(sl);
1153 >            assertValid(sl, stamp);
1154 >            assertNoLongerValidStampsThrow.run();
1155 >            assertThrows(IllegalMonitorStateException.class,
1156 >                         () -> sl.unlockWrite(stamp),
1157 >                         () -> sl.unlockRead(sl.tryOptimisticRead()),
1158 >                         () -> sl.unlockRead(0L));
1159 >            readUnlocker.accept(sl, stamp);
1160 >            assertUnlocked(sl);
1161 >            assertNoLongerValidStampsThrow.run();
1162 >        }
1163 >
1164 >        for (Function<StampedLock, Long> writeLocker : writeLockers())
1165 >        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
1166 >            final long stamp = writeLocker.apply(sl);
1167 >            assertValid(sl, stamp);
1168 >            assertNoLongerValidStampsThrow.run();
1169 >            assertThrows(IllegalMonitorStateException.class,
1170 >                         () -> sl.unlockRead(stamp),
1171 >                         () -> sl.unlockWrite(0L));
1172 >            writeUnlocker.accept(sl, stamp);
1173 >            assertUnlocked(sl);
1174 >            assertNoLongerValidStampsThrow.run();
1175 >        }
1176 >    }
1177 >
1178 >    /**
1179 >     * Read locks can be very deeply nested
1180 >     */
1181 >    public void testDeeplyNestedReadLocks() {
1182 >        final StampedLock lock = new StampedLock();
1183 >        final int depth = 300;
1184 >        final long[] stamps = new long[depth];
1185 >        final List<Function<StampedLock, Long>> readLockers = readLockers();
1186 >        final List<BiConsumer<StampedLock, Long>> readUnlockers = readUnlockers();
1187 >        for (int i = 0; i < depth; i++) {
1188 >            Function<StampedLock, Long> readLocker
1189 >                = readLockers.get(i % readLockers.size());
1190 >            long stamp = readLocker.apply(lock);
1191 >            assertEquals(i + 1, lock.getReadLockCount());
1192 >            assertTrue(lock.isReadLocked());
1193 >            stamps[i] = stamp;
1194 >        }
1195 >        for (int i = 0; i < depth; i++) {
1196 >            BiConsumer<StampedLock, Long> readUnlocker
1197 >                = readUnlockers.get(i % readUnlockers.size());
1198 >            assertEquals(depth - i, lock.getReadLockCount());
1199 >            assertTrue(lock.isReadLocked());
1200 >            readUnlocker.accept(lock, stamps[depth - 1 - i]);
1201 >        }
1202 >        assertUnlocked(lock);
1203 >    }
1204 >
1205 >    /**
1206 >     * Stamped locks are not reentrant.
1207 >     */
1208 >    public void testNonReentrant() throws InterruptedException {
1209 >        final StampedLock lock = new StampedLock();
1210 >        long stamp;
1211 >
1212 >        stamp = lock.writeLock();
1213 >        assertValid(lock, stamp);
1214 >        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
1215 >        assertEquals(0L, lock.tryReadLock(0L, DAYS));
1216 >        assertValid(lock, stamp);
1217 >        lock.unlockWrite(stamp);
1218 >
1219 >        stamp = lock.tryWriteLock(1L, DAYS);
1220 >        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
1221 >        assertValid(lock, stamp);
1222 >        lock.unlockWrite(stamp);
1223 >
1224 >        stamp = lock.readLock();
1225 >        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
1226 >        assertValid(lock, stamp);
1227 >        lock.unlockRead(stamp);
1228 >    }
1229 >
1230 >    /**
1231 >     * """StampedLocks have no notion of ownership. Locks acquired in
1232 >     * one thread can be released or converted in another."""
1233 >     */
1234 >    public void testNoOwnership() throws Throwable {
1235 >        ArrayList<Future<?>> futures = new ArrayList<>();
1236 >        for (Function<StampedLock, Long> writeLocker : writeLockers())
1237 >        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
1238 >            StampedLock lock = new StampedLock();
1239 >            long stamp = writeLocker.apply(lock);
1240 >            futures.add(cachedThreadPool.submit(new CheckedRunnable() {
1241 >                public void realRun() {
1242 >                    writeUnlocker.accept(lock, stamp);
1243 >                    assertUnlocked(lock);
1244 >                    assertFalse(lock.validate(stamp));
1245 >                }}));
1246 >        }
1247 >        for (Future<?> future : futures)
1248 >            assertNull(future.get());
1249 >    }
1250 >
1251 >    /** Tries out sample usage code from StampedLock javadoc. */
1252 >    public void testSampleUsage() throws Throwable {
1253 >        class Point {
1254 >            private double x, y;
1255 >            private final StampedLock sl = new StampedLock();
1256 >
1257 >            void move(double deltaX, double deltaY) { // an exclusively locked method
1258 >                long stamp = sl.writeLock();
1259 >                try {
1260 >                    x += deltaX;
1261 >                    y += deltaY;
1262 >                } finally {
1263 >                    sl.unlockWrite(stamp);
1264 >                }
1265 >            }
1266 >
1267 >            double distanceFromOrigin() { // A read-only method
1268 >                double currentX, currentY;
1269 >                long stamp = sl.tryOptimisticRead();
1270 >                do {
1271 >                    if (stamp == 0L)
1272 >                        stamp = sl.readLock();
1273 >                    try {
1274 >                        // possibly racy reads
1275 >                        currentX = x;
1276 >                        currentY = y;
1277 >                    } finally {
1278 >                        stamp = sl.tryConvertToOptimisticRead(stamp);
1279 >                    }
1280 >                } while (stamp == 0);
1281 >                return Math.hypot(currentX, currentY);
1282 >            }
1283 >
1284 >            double distanceFromOrigin2() {
1285 >                long stamp = sl.tryOptimisticRead();
1286 >                try {
1287 >                    retryHoldingLock:
1288 >                    for (;; stamp = sl.readLock()) {
1289 >                        if (stamp == 0L)
1290 >                            continue retryHoldingLock;
1291 >                        // possibly racy reads
1292 >                        double currentX = x;
1293 >                        double currentY = y;
1294 >                        if (!sl.validate(stamp))
1295 >                            continue retryHoldingLock;
1296 >                        return Math.hypot(currentX, currentY);
1297 >                    }
1298 >                } finally {
1299 >                    if (StampedLock.isReadLockStamp(stamp))
1300 >                        sl.unlockRead(stamp);
1301 >                }
1302 >            }
1303 >
1304 >            void moveIfAtOrigin(double newX, double newY) {
1305 >                long stamp = sl.readLock();
1306 >                try {
1307 >                    while (x == 0.0 && y == 0.0) {
1308 >                        long ws = sl.tryConvertToWriteLock(stamp);
1309 >                        if (ws != 0L) {
1310 >                            stamp = ws;
1311 >                            x = newX;
1312 >                            y = newY;
1313 >                            return;
1314 >                        }
1315 >                        else {
1316 >                            sl.unlockRead(stamp);
1317 >                            stamp = sl.writeLock();
1318 >                        }
1319 >                    }
1320 >                } finally {
1321 >                    sl.unlock(stamp);
1322 >                }
1323 >            }
1324 >        }
1325 >
1326 >        Point p = new Point();
1327 >        p.move(3.0, 4.0);
1328 >        assertEquals(5.0, p.distanceFromOrigin());
1329 >        p.moveIfAtOrigin(5.0, 12.0);
1330 >        assertEquals(5.0, p.distanceFromOrigin2());
1331 >    }
1332 >
1333 >    /**
1334 >     * Stamp inspection methods work as expected, and do not inspect
1335 >     * the state of the lock itself.
1336 >     */
1337 >    public void testStampStateInspectionMethods() {
1338 >        StampedLock lock = new StampedLock();
1339 >
1340 >        assertFalse(isWriteLockStamp(0L));
1341 >        assertFalse(isReadLockStamp(0L));
1342 >        assertFalse(isLockStamp(0L));
1343 >        assertFalse(isOptimisticReadStamp(0L));
1344 >
1345 >        {
1346 >            long stamp = lock.writeLock();
1347 >            for (int i = 0; i < 2; i++) {
1348 >                assertTrue(isWriteLockStamp(stamp));
1349 >                assertFalse(isReadLockStamp(stamp));
1350 >                assertTrue(isLockStamp(stamp));
1351 >                assertFalse(isOptimisticReadStamp(stamp));
1352 >                if (i == 0)
1353 >                    lock.unlockWrite(stamp);
1354 >            }
1355 >        }
1356 >
1357 >        {
1358 >            long stamp = lock.readLock();
1359 >            for (int i = 0; i < 2; i++) {
1360 >                assertFalse(isWriteLockStamp(stamp));
1361 >                assertTrue(isReadLockStamp(stamp));
1362 >                assertTrue(isLockStamp(stamp));
1363 >                assertFalse(isOptimisticReadStamp(stamp));
1364 >                if (i == 0)
1365 >                    lock.unlockRead(stamp);
1366 >            }
1367 >        }
1368 >
1369 >        {
1370 >            long optimisticStamp = lock.tryOptimisticRead();
1371 >            long readStamp = lock.tryConvertToReadLock(optimisticStamp);
1372 >            long writeStamp = lock.tryConvertToWriteLock(readStamp);
1373 >            for (int i = 0; i < 2; i++) {
1374 >                assertFalse(isWriteLockStamp(optimisticStamp));
1375 >                assertFalse(isReadLockStamp(optimisticStamp));
1376 >                assertFalse(isLockStamp(optimisticStamp));
1377 >                assertTrue(isOptimisticReadStamp(optimisticStamp));
1378 >
1379 >                assertFalse(isWriteLockStamp(readStamp));
1380 >                assertTrue(isReadLockStamp(readStamp));
1381 >                assertTrue(isLockStamp(readStamp));
1382 >                assertFalse(isOptimisticReadStamp(readStamp));
1383 >
1384 >                assertTrue(isWriteLockStamp(writeStamp));
1385 >                assertFalse(isReadLockStamp(writeStamp));
1386 >                assertTrue(isLockStamp(writeStamp));
1387 >                assertFalse(isOptimisticReadStamp(writeStamp));
1388 >                if (i == 0)
1389 >                    lock.unlockWrite(writeStamp);
1390 >            }
1391 >        }
1392 >    }
1393 >
1394 >    /**
1395 >     * Multiple threads repeatedly contend for the same lock.
1396 >     */
1397 >    public void testConcurrentAccess() throws Exception {
1398 >        final StampedLock sl = new StampedLock();
1399 >        final Lock wl = sl.asWriteLock();
1400 >        final Lock rl = sl.asReadLock();
1401 >        final long testDurationMillis = expensiveTests ? 1000 : 2;
1402 >        final int nTasks = ThreadLocalRandom.current().nextInt(1, 10);
1403 >        final AtomicBoolean done = new AtomicBoolean(false);
1404 >        final List<CompletableFuture<?>> futures = new ArrayList<>();
1405 >        final List<Callable<Long>> stampedWriteLockers = List.of(
1406 >            () -> sl.writeLock(),
1407 >            () -> writeLockInterruptiblyUninterrupted(sl),
1408 >            () -> tryWriteLockUninterrupted(sl, LONG_DELAY_MS, MILLISECONDS),
1409 >            () -> {
1410 >                long stamp;
1411 >                do { stamp = sl.tryConvertToWriteLock(sl.tryOptimisticRead()); }
1412 >                while (stamp == 0L);
1413 >                return stamp;
1414 >            },
1415 >            () -> {
1416 >              long stamp;
1417 >              do { stamp = sl.tryWriteLock(); } while (stamp == 0L);
1418 >              return stamp;
1419 >            },
1420 >            () -> {
1421 >              long stamp;
1422 >              do { stamp = sl.tryWriteLock(0L, DAYS); } while (stamp == 0L);
1423 >              return stamp;
1424 >            });
1425 >        final List<Callable<Long>> stampedReadLockers = List.of(
1426 >            () -> sl.readLock(),
1427 >            () -> readLockInterruptiblyUninterrupted(sl),
1428 >            () -> tryReadLockUninterrupted(sl, LONG_DELAY_MS, MILLISECONDS),
1429 >            () -> {
1430 >                long stamp;
1431 >                do { stamp = sl.tryConvertToReadLock(sl.tryOptimisticRead()); }
1432 >                while (stamp == 0L);
1433 >                return stamp;
1434 >            },
1435 >            () -> {
1436 >              long stamp;
1437 >              do { stamp = sl.tryReadLock(); } while (stamp == 0L);
1438 >              return stamp;
1439 >            },
1440 >            () -> {
1441 >              long stamp;
1442 >              do { stamp = sl.tryReadLock(0L, DAYS); } while (stamp == 0L);
1443 >              return stamp;
1444 >            });
1445 >        final List<Consumer<Long>> stampedWriteUnlockers = List.of(
1446 >            stamp -> sl.unlockWrite(stamp),
1447 >            stamp -> sl.unlock(stamp),
1448 >            stamp -> assertTrue(sl.tryUnlockWrite()),
1449 >            stamp -> wl.unlock(),
1450 >            stamp -> sl.tryConvertToOptimisticRead(stamp));
1451 >        final List<Consumer<Long>> stampedReadUnlockers = List.of(
1452 >            stamp -> sl.unlockRead(stamp),
1453 >            stamp -> sl.unlock(stamp),
1454 >            stamp -> assertTrue(sl.tryUnlockRead()),
1455 >            stamp -> rl.unlock(),
1456 >            stamp -> sl.tryConvertToOptimisticRead(stamp));
1457 >        final Action writer = () -> {
1458 >            // repeatedly acquires write lock
1459 >            var locker = chooseRandomly(stampedWriteLockers);
1460 >            var unlocker = chooseRandomly(stampedWriteUnlockers);
1461 >            while (!done.getAcquire()) {
1462 >                long stamp = locker.call();
1463 >                try {
1464 >                    assertTrue(isWriteLockStamp(stamp));
1465 >                    assertTrue(sl.isWriteLocked());
1466 >                    assertFalse(isReadLockStamp(stamp));
1467 >                    assertFalse(sl.isReadLocked());
1468 >                    assertEquals(0, sl.getReadLockCount());
1469 >                    assertTrue(sl.validate(stamp));
1470 >                } finally {
1471 >                    unlocker.accept(stamp);
1472 >                }
1473 >            }
1474 >        };
1475 >        final Action reader = () -> {
1476 >            // repeatedly acquires read lock
1477 >            var locker = chooseRandomly(stampedReadLockers);
1478 >            var unlocker = chooseRandomly(stampedReadUnlockers);
1479 >            while (!done.getAcquire()) {
1480 >                long stamp = locker.call();
1481 >                try {
1482 >                    assertFalse(isWriteLockStamp(stamp));
1483 >                    assertFalse(sl.isWriteLocked());
1484 >                    assertTrue(isReadLockStamp(stamp));
1485 >                    assertTrue(sl.isReadLocked());
1486 >                    assertTrue(sl.getReadLockCount() > 0);
1487 >                    assertTrue(sl.validate(stamp));
1488 >                } finally {
1489 >                    unlocker.accept(stamp);
1490 >                }
1491 >            }
1492 >        };
1493 >        for (int i = nTasks; i--> 0; ) {
1494 >            Action task = chooseRandomly(writer, reader);
1495 >            futures.add(CompletableFuture.runAsync(checkedRunnable(task)));
1496 >        }
1497 >        Thread.sleep(testDurationMillis);
1498 >        done.setRelease(true);
1499 >        for (var future : futures)
1500 >            checkTimedGet(future, null);
1501 >    }
1502  
1503   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines