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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines