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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines