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

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines