ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/StampedLockTest.java
Revision: 1.36
Committed: Mon May 29 19:15:03 2017 UTC (6 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.35: +4 -2 lines
Log Message:
more timeout handling rework; remove most uses of SMALL_DELAY_MS; randomize timeouts and TimeUnits; remove hardcoded 5 second timeouts

File Contents

# User Rev Content
1 jsr166 1.1 /*
2     * Written by Doug Lea and Martin Buchholz
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     */
7    
8 jsr166 1.25 import static java.util.concurrent.TimeUnit.DAYS;
9 jsr166 1.10 import static java.util.concurrent.TimeUnit.MILLISECONDS;
10 jsr166 1.27 import static java.util.concurrent.TimeUnit.SECONDS;
11 jsr166 1.10
12 jsr166 1.25 import java.util.ArrayList;
13     import java.util.List;
14 jsr166 1.10 import java.util.concurrent.CountDownLatch;
15 jsr166 1.27 import java.util.concurrent.Future;
16 jsr166 1.25 import java.util.concurrent.TimeUnit;
17 jsr166 1.1 import java.util.concurrent.locks.Lock;
18 jsr166 1.2 import java.util.concurrent.locks.StampedLock;
19 jsr166 1.25 import java.util.function.BiConsumer;
20     import java.util.function.Function;
21 jsr166 1.10
22     import junit.framework.Test;
23     import junit.framework.TestSuite;
24 jsr166 1.1
25     public class StampedLockTest extends JSR166TestCase {
26     public static void main(String[] args) {
27 jsr166 1.13 main(suite(), args);
28 jsr166 1.1 }
29     public static Test suite() {
30     return new TestSuite(StampedLockTest.class);
31     }
32    
33 dl 1.4 /**
34 jsr166 1.27 * Releases write lock, checking isWriteLocked before and after
35 dl 1.4 */
36 jsr166 1.27 void releaseWriteLock(StampedLock lock, long stamp) {
37     assertTrue(lock.isWriteLocked());
38     assertValid(lock, stamp);
39     lock.unlockWrite(stamp);
40     assertFalse(lock.isWriteLocked());
41     assertFalse(lock.validate(stamp));
42 dl 1.4 }
43    
44     /**
45 jsr166 1.27 * Releases read lock, checking isReadLocked before and after
46 dl 1.4 */
47 jsr166 1.27 void releaseReadLock(StampedLock lock, long stamp) {
48     assertTrue(lock.isReadLocked());
49     assertValid(lock, stamp);
50     lock.unlockRead(stamp);
51     assertFalse(lock.isReadLocked());
52     assertTrue(lock.validate(stamp));
53 dl 1.4 }
54    
55 jsr166 1.27 long assertNonZero(long v) {
56     assertTrue(v != 0L);
57     return v;
58 dl 1.4 }
59    
60 jsr166 1.27 long assertValid(StampedLock lock, long stamp) {
61     assertTrue(stamp != 0L);
62     assertTrue(lock.validate(stamp));
63     return stamp;
64 dl 1.4 }
65    
66 jsr166 1.27 void assertUnlocked(StampedLock lock) {
67 dl 1.4 assertFalse(lock.isReadLocked());
68     assertFalse(lock.isWriteLocked());
69 jsr166 1.27 assertEquals(0, lock.getReadLockCount());
70     assertValid(lock, lock.tryOptimisticRead());
71     }
72    
73     List<Action> lockLockers(Lock lock) {
74     List<Action> lockers = new ArrayList<>();
75     lockers.add(() -> lock.lock());
76     lockers.add(() -> lock.lockInterruptibly());
77     lockers.add(() -> lock.tryLock());
78     lockers.add(() -> lock.tryLock(Long.MIN_VALUE, DAYS));
79     lockers.add(() -> lock.tryLock(0L, DAYS));
80     lockers.add(() -> lock.tryLock(Long.MAX_VALUE, DAYS));
81     return lockers;
82     }
83    
84     List<Function<StampedLock, Long>> readLockers() {
85     List<Function<StampedLock, Long>> readLockers = new ArrayList<>();
86 jsr166 1.29 readLockers.add(sl -> sl.readLock());
87     readLockers.add(sl -> sl.tryReadLock());
88     readLockers.add(sl -> readLockInterruptiblyUninterrupted(sl));
89     readLockers.add(sl -> tryReadLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
90     readLockers.add(sl -> tryReadLockUninterrupted(sl, 0L, DAYS));
91     readLockers.add(sl -> sl.tryConvertToReadLock(sl.tryOptimisticRead()));
92 jsr166 1.27 return readLockers;
93 dl 1.4 }
94    
95 jsr166 1.27 List<BiConsumer<StampedLock, Long>> readUnlockers() {
96     List<BiConsumer<StampedLock, Long>> readUnlockers = new ArrayList<>();
97     readUnlockers.add((sl, stamp) -> sl.unlockRead(stamp));
98     readUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockRead()));
99     readUnlockers.add((sl, stamp) -> sl.asReadLock().unlock());
100     readUnlockers.add((sl, stamp) -> sl.unlock(stamp));
101     readUnlockers.add((sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
102     return readUnlockers;
103 dl 1.4 }
104    
105 jsr166 1.27 List<Function<StampedLock, Long>> writeLockers() {
106     List<Function<StampedLock, Long>> writeLockers = new ArrayList<>();
107 jsr166 1.29 writeLockers.add(sl -> sl.writeLock());
108     writeLockers.add(sl -> sl.tryWriteLock());
109     writeLockers.add(sl -> writeLockInterruptiblyUninterrupted(sl));
110     writeLockers.add(sl -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
111     writeLockers.add(sl -> tryWriteLockUninterrupted(sl, 0L, DAYS));
112     writeLockers.add(sl -> sl.tryConvertToWriteLock(sl.tryOptimisticRead()));
113 jsr166 1.27 return writeLockers;
114 dl 1.4 }
115    
116 jsr166 1.27 List<BiConsumer<StampedLock, Long>> writeUnlockers() {
117     List<BiConsumer<StampedLock, Long>> writeUnlockers = new ArrayList<>();
118     writeUnlockers.add((sl, stamp) -> sl.unlockWrite(stamp));
119     writeUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockWrite()));
120     writeUnlockers.add((sl, stamp) -> sl.asWriteLock().unlock());
121     writeUnlockers.add((sl, stamp) -> sl.unlock(stamp));
122     writeUnlockers.add((sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
123     return writeUnlockers;
124 dl 1.4 }
125    
126     /**
127 jsr166 1.27 * Constructed StampedLock is in unlocked state
128 dl 1.4 */
129 jsr166 1.27 public void testConstructor() {
130     assertUnlocked(new StampedLock());
131 dl 1.4 }
132    
133     /**
134 jsr166 1.27 * write-locking, then unlocking, an unlocked lock succeed
135 dl 1.4 */
136 jsr166 1.27 public void testWriteLock_lockUnlock() {
137 dl 1.4 StampedLock lock = new StampedLock();
138 jsr166 1.27
139     for (Function<StampedLock, Long> writeLocker : writeLockers())
140     for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
141     assertFalse(lock.isWriteLocked());
142     assertFalse(lock.isReadLocked());
143     assertEquals(0, lock.getReadLockCount());
144    
145     long s = writeLocker.apply(lock);
146     assertValid(lock, s);
147     assertTrue(lock.isWriteLocked());
148     assertFalse(lock.isReadLocked());
149     assertEquals(0, lock.getReadLockCount());
150     writeUnlocker.accept(lock, s);
151     assertUnlocked(lock);
152     }
153 dl 1.4 }
154    
155     /**
156 jsr166 1.27 * read-locking, then unlocking, an unlocked lock succeed
157 dl 1.4 */
158 jsr166 1.27 public void testReadLock_lockUnlock() {
159 dl 1.4 StampedLock lock = new StampedLock();
160 jsr166 1.27
161     for (Function<StampedLock, Long> readLocker : readLockers())
162     for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
163     long s = 42;
164     for (int i = 0; i < 2; i++) {
165     s = assertValid(lock, readLocker.apply(lock));
166     assertFalse(lock.isWriteLocked());
167     assertTrue(lock.isReadLocked());
168     assertEquals(i + 1, lock.getReadLockCount());
169     }
170     for (int i = 0; i < 2; i++) {
171     assertFalse(lock.isWriteLocked());
172     assertTrue(lock.isReadLocked());
173     assertEquals(2 - i, lock.getReadLockCount());
174     readUnlocker.accept(lock, s);
175     }
176     assertUnlocked(lock);
177     }
178 dl 1.4 }
179    
180     /**
181 jsr166 1.27 * tryUnlockWrite fails if not write locked
182 dl 1.4 */
183 jsr166 1.27 public void testTryUnlockWrite_failure() {
184 dl 1.4 StampedLock lock = new StampedLock();
185 jsr166 1.27 assertFalse(lock.tryUnlockWrite());
186    
187     for (Function<StampedLock, Long> readLocker : readLockers())
188     for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
189     long s = assertValid(lock, readLocker.apply(lock));
190     assertFalse(lock.tryUnlockWrite());
191     assertTrue(lock.isReadLocked());
192     readUnlocker.accept(lock, s);
193     assertUnlocked(lock);
194     }
195 dl 1.4 }
196    
197     /**
198 jsr166 1.27 * tryUnlockRead fails if not read locked
199 dl 1.4 */
200 jsr166 1.27 public void testTryUnlockRead_failure() {
201 dl 1.4 StampedLock lock = new StampedLock();
202 jsr166 1.27 assertFalse(lock.tryUnlockRead());
203    
204     for (Function<StampedLock, Long> writeLocker : writeLockers())
205     for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
206     long s = writeLocker.apply(lock);
207     assertFalse(lock.tryUnlockRead());
208     assertTrue(lock.isWriteLocked());
209     writeUnlocker.accept(lock, s);
210     assertUnlocked(lock);
211     }
212 dl 1.4 }
213    
214     /**
215 jsr166 1.27 * validate(0L) fails
216 dl 1.4 */
217     public void testValidate0() {
218     StampedLock lock = new StampedLock();
219     assertFalse(lock.validate(0L));
220     }
221    
222     /**
223 jsr166 1.27 * A stamp obtained from a successful lock operation validates while the lock is held
224 dl 1.4 */
225 jsr166 1.11 public void testValidate() throws InterruptedException {
226     StampedLock lock = new StampedLock();
227 jsr166 1.27
228     for (Function<StampedLock, Long> readLocker : readLockers())
229     for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
230     long s = assertNonZero(readLocker.apply(lock));
231     assertTrue(lock.validate(s));
232     readUnlocker.accept(lock, s);
233     }
234    
235     for (Function<StampedLock, Long> writeLocker : writeLockers())
236     for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
237     long s = assertNonZero(writeLocker.apply(lock));
238     assertTrue(lock.validate(s));
239     writeUnlocker.accept(lock, s);
240     }
241 dl 1.4 }
242    
243     /**
244     * A stamp obtained from an unsuccessful lock operation does not validate
245     */
246 jsr166 1.11 public void testValidate2() throws InterruptedException {
247     StampedLock lock = new StampedLock();
248 jsr166 1.27 long s = assertNonZero(lock.writeLock());
249 jsr166 1.11 assertTrue(lock.validate(s));
250     assertFalse(lock.validate(lock.tryWriteLock()));
251 jsr166 1.36 assertFalse(lock.validate(lock.tryWriteLock(randomExpiredTimeout(),
252     randomTimeUnit())));
253 jsr166 1.11 assertFalse(lock.validate(lock.tryReadLock()));
254 jsr166 1.36 assertFalse(lock.validate(lock.tryWriteLock(randomExpiredTimeout(),
255     randomTimeUnit())));
256 jsr166 1.11 assertFalse(lock.validate(lock.tryOptimisticRead()));
257     lock.unlockWrite(s);
258 dl 1.4 }
259    
260 jsr166 1.27 void assertThrowInterruptedExceptionWhenPreInterrupted(Action[] actions) {
261     for (Action action : actions) {
262     Thread.currentThread().interrupt();
263     try {
264     action.run();
265     shouldThrow();
266     }
267     catch (InterruptedException success) {}
268     catch (Throwable fail) { threadUnexpectedException(fail); }
269     assertFalse(Thread.interrupted());
270     }
271     }
272    
273 dl 1.4 /**
274 jsr166 1.27 * interruptible operations throw InterruptedException when pre-interrupted
275 dl 1.4 */
276 jsr166 1.27 public void testInterruptibleOperationsThrowInterruptedExceptionWhenPreInterrupted() {
277 dl 1.4 final StampedLock lock = new StampedLock();
278 jsr166 1.12
279 jsr166 1.27 Action[] interruptibleLockActions = {
280     () -> lock.writeLockInterruptibly(),
281     () -> lock.tryWriteLock(Long.MIN_VALUE, DAYS),
282     () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
283     () -> lock.readLockInterruptibly(),
284     () -> lock.tryReadLock(Long.MIN_VALUE, DAYS),
285     () -> lock.tryReadLock(Long.MAX_VALUE, DAYS),
286     () -> lock.asWriteLock().lockInterruptibly(),
287     () -> lock.asWriteLock().tryLock(0L, DAYS),
288     () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
289     () -> lock.asReadLock().lockInterruptibly(),
290     () -> lock.asReadLock().tryLock(0L, DAYS),
291     () -> lock.asReadLock().tryLock(Long.MAX_VALUE, DAYS),
292     };
293     shuffle(interruptibleLockActions);
294    
295     assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
296     {
297     long s = lock.writeLock();
298     assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
299     lock.unlockWrite(s);
300     }
301     {
302     long s = lock.readLock();
303     assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
304     lock.unlockRead(s);
305     }
306     }
307    
308     void assertThrowInterruptedExceptionWhenInterrupted(Action[] actions) {
309     int n = actions.length;
310     Future<?>[] futures = new Future<?>[n];
311     CountDownLatch threadsStarted = new CountDownLatch(n);
312     CountDownLatch done = new CountDownLatch(n);
313    
314     for (int i = 0; i < n; i++) {
315     Action action = actions[i];
316     futures[i] = cachedThreadPool.submit(new CheckedRunnable() {
317     public void realRun() throws Throwable {
318     threadsStarted.countDown();
319     try {
320     action.run();
321     shouldThrow();
322     }
323     catch (InterruptedException success) {}
324     catch (Throwable fail) { threadUnexpectedException(fail); }
325     assertFalse(Thread.interrupted());
326     done.countDown();
327     }});
328     }
329    
330     await(threadsStarted);
331     assertEquals(n, done.getCount());
332     for (Future<?> future : futures) // Interrupt all the tasks
333     future.cancel(true);
334     await(done);
335 dl 1.4 }
336    
337     /**
338 jsr166 1.27 * interruptible operations throw InterruptedException when write locked and interrupted
339 dl 1.4 */
340 jsr166 1.27 public void testInterruptibleOperationsThrowInterruptedExceptionWriteLockedInterrupted() {
341 dl 1.4 final StampedLock lock = new StampedLock();
342     long s = lock.writeLock();
343 jsr166 1.12
344 jsr166 1.27 Action[] interruptibleLockBlockingActions = {
345     () -> lock.writeLockInterruptibly(),
346     () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
347     () -> lock.readLockInterruptibly(),
348     () -> lock.tryReadLock(Long.MAX_VALUE, DAYS),
349     () -> lock.asWriteLock().lockInterruptibly(),
350     () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
351     () -> lock.asReadLock().lockInterruptibly(),
352     () -> lock.asReadLock().tryLock(Long.MAX_VALUE, DAYS),
353     };
354     shuffle(interruptibleLockBlockingActions);
355    
356     assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions);
357 dl 1.4 }
358    
359     /**
360 jsr166 1.27 * interruptible operations throw InterruptedException when read locked and interrupted
361 dl 1.4 */
362 jsr166 1.27 public void testInterruptibleOperationsThrowInterruptedExceptionReadLockedInterrupted() {
363 dl 1.4 final StampedLock lock = new StampedLock();
364 jsr166 1.27 long s = lock.readLock();
365    
366     Action[] interruptibleLockBlockingActions = {
367     () -> lock.writeLockInterruptibly(),
368     () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
369     () -> lock.asWriteLock().lockInterruptibly(),
370     () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
371     };
372     shuffle(interruptibleLockBlockingActions);
373 jsr166 1.12
374 jsr166 1.27 assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions);
375 dl 1.4 }
376    
377     /**
378 jsr166 1.27 * Non-interruptible operations ignore and preserve interrupt status
379 dl 1.4 */
380 jsr166 1.27 public void testNonInterruptibleOperationsIgnoreInterrupts() {
381 dl 1.4 final StampedLock lock = new StampedLock();
382 jsr166 1.27 Thread.currentThread().interrupt();
383    
384     for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
385     long s = assertValid(lock, lock.readLock());
386     readUnlocker.accept(lock, s);
387     s = assertValid(lock, lock.tryReadLock());
388     readUnlocker.accept(lock, s);
389     }
390    
391     lock.asReadLock().lock();
392     lock.asReadLock().unlock();
393    
394     for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
395     long s = assertValid(lock, lock.writeLock());
396     writeUnlocker.accept(lock, s);
397     s = assertValid(lock, lock.tryWriteLock());
398     writeUnlocker.accept(lock, s);
399     }
400    
401     lock.asWriteLock().lock();
402     lock.asWriteLock().unlock();
403 jsr166 1.12
404 jsr166 1.27 assertTrue(Thread.interrupted());
405 dl 1.4 }
406    
407     /**
408     * tryWriteLock on an unlocked lock succeeds
409     */
410 jsr166 1.27 public void testTryWriteLock() {
411 dl 1.4 final StampedLock lock = new StampedLock();
412     long s = lock.tryWriteLock();
413     assertTrue(s != 0L);
414     assertTrue(lock.isWriteLocked());
415 jsr166 1.27 assertEquals(0L, lock.tryWriteLock());
416 dl 1.4 releaseWriteLock(lock, s);
417     }
418    
419     /**
420     * tryWriteLock fails if locked
421     */
422 jsr166 1.27 public void testTryWriteLockWhenLocked() {
423 dl 1.4 final StampedLock lock = new StampedLock();
424     long s = lock.writeLock();
425     Thread t = newStartedThread(new CheckedRunnable() {
426     public void realRun() {
427 jsr166 1.27 assertEquals(0L, lock.tryWriteLock());
428 dl 1.4 }});
429 jsr166 1.12
430 jsr166 1.27 assertEquals(0L, lock.tryWriteLock());
431 dl 1.4 awaitTermination(t);
432     releaseWriteLock(lock, s);
433     }
434    
435     /**
436     * tryReadLock fails if write-locked
437     */
438 jsr166 1.27 public void testTryReadLockWhenLocked() {
439 dl 1.4 final StampedLock lock = new StampedLock();
440     long s = lock.writeLock();
441     Thread t = newStartedThread(new CheckedRunnable() {
442     public void realRun() {
443 jsr166 1.27 assertEquals(0L, lock.tryReadLock());
444 dl 1.4 }});
445 jsr166 1.12
446 jsr166 1.27 assertEquals(0L, lock.tryReadLock());
447 dl 1.4 awaitTermination(t);
448     releaseWriteLock(lock, s);
449     }
450    
451     /**
452     * Multiple threads can hold a read lock when not write-locked
453     */
454     public void testMultipleReadLocks() {
455     final StampedLock lock = new StampedLock();
456     final long s = lock.readLock();
457     Thread t = newStartedThread(new CheckedRunnable() {
458     public void realRun() throws InterruptedException {
459     long s2 = lock.tryReadLock();
460 jsr166 1.27 assertValid(lock, s2);
461 dl 1.4 lock.unlockRead(s2);
462     long s3 = lock.tryReadLock(LONG_DELAY_MS, MILLISECONDS);
463 jsr166 1.27 assertValid(lock, s3);
464 dl 1.4 lock.unlockRead(s3);
465     long s4 = lock.readLock();
466 jsr166 1.27 assertValid(lock, s4);
467 dl 1.4 lock.unlockRead(s4);
468 jsr166 1.27 lock.asReadLock().lock();
469     lock.asReadLock().unlock();
470     lock.asReadLock().lockInterruptibly();
471     lock.asReadLock().unlock();
472     lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS);
473     lock.asReadLock().unlock();
474 dl 1.4 }});
475 jsr166 1.12
476 dl 1.4 awaitTermination(t);
477     lock.unlockRead(s);
478     }
479    
480     /**
481 jsr166 1.33 * writeLock() succeeds only after a reading thread unlocks
482 dl 1.4 */
483 jsr166 1.11 public void testWriteAfterReadLock() throws InterruptedException {
484 jsr166 1.33 final CountDownLatch aboutToLock = new CountDownLatch(1);
485 dl 1.4 final StampedLock lock = new StampedLock();
486     long rs = lock.readLock();
487     Thread t = newStartedThread(new CheckedRunnable() {
488     public void realRun() {
489 jsr166 1.33 aboutToLock.countDown();
490 dl 1.4 long s = lock.writeLock();
491 jsr166 1.33 assertTrue(lock.isWriteLocked());
492     assertFalse(lock.isReadLocked());
493 dl 1.4 lock.unlockWrite(s);
494     }});
495 jsr166 1.12
496 jsr166 1.34 await(aboutToLock);
497 jsr166 1.35 assertThreadBlocks(t, Thread.State.WAITING);
498 jsr166 1.11 assertFalse(lock.isWriteLocked());
499 jsr166 1.33 assertTrue(lock.isReadLocked());
500 jsr166 1.11 lock.unlockRead(rs);
501     awaitTermination(t);
502 jsr166 1.33 assertUnlocked(lock);
503 dl 1.4 }
504    
505     /**
506 jsr166 1.33 * writeLock() succeeds only after reading threads unlock
507 dl 1.4 */
508     public void testWriteAfterMultipleReadLocks() {
509     final StampedLock lock = new StampedLock();
510     long s = lock.readLock();
511     Thread t1 = newStartedThread(new CheckedRunnable() {
512     public void realRun() {
513     long rs = lock.readLock();
514     lock.unlockRead(rs);
515     }});
516 jsr166 1.12
517 dl 1.4 awaitTermination(t1);
518    
519     Thread t2 = newStartedThread(new CheckedRunnable() {
520     public void realRun() {
521     long ws = lock.writeLock();
522     lock.unlockWrite(ws);
523     }});
524 jsr166 1.12
525 jsr166 1.27 assertTrue(lock.isReadLocked());
526 dl 1.4 assertFalse(lock.isWriteLocked());
527     lock.unlockRead(s);
528     awaitTermination(t2);
529 jsr166 1.33 assertUnlocked(lock);
530 dl 1.4 }
531    
532     /**
533 jsr166 1.33 * readLock() succeed only after a writing thread unlocks
534 dl 1.4 */
535     public void testReadAfterWriteLock() {
536     final StampedLock lock = new StampedLock();
537 jsr166 1.27 final CountDownLatch threadsStarted = new CountDownLatch(2);
538 dl 1.4 final long s = lock.writeLock();
539 jsr166 1.33 final Runnable acquireReleaseReadLock = new CheckedRunnable() {
540 dl 1.4 public void realRun() {
541 jsr166 1.27 threadsStarted.countDown();
542 dl 1.4 long rs = lock.readLock();
543 jsr166 1.33 assertTrue(lock.isReadLocked());
544     assertFalse(lock.isWriteLocked());
545 dl 1.4 lock.unlockRead(rs);
546 jsr166 1.33 }};
547     Thread t1 = newStartedThread(acquireReleaseReadLock);
548     Thread t2 = newStartedThread(acquireReleaseReadLock);
549 dl 1.4
550 jsr166 1.27 await(threadsStarted);
551 jsr166 1.35 assertThreadBlocks(t1, Thread.State.WAITING);
552     assertThreadBlocks(t2, Thread.State.WAITING);
553 jsr166 1.33 assertTrue(lock.isWriteLocked());
554     assertFalse(lock.isReadLocked());
555 dl 1.4 releaseWriteLock(lock, s);
556     awaitTermination(t1);
557     awaitTermination(t2);
558 jsr166 1.33 assertUnlocked(lock);
559 dl 1.4 }
560    
561     /**
562 jsr166 1.27 * tryReadLock succeeds if read locked but not write locked
563 dl 1.4 */
564     public void testTryLockWhenReadLocked() {
565     final StampedLock lock = new StampedLock();
566     long s = lock.readLock();
567     Thread t = newStartedThread(new CheckedRunnable() {
568     public void realRun() {
569     long rs = lock.tryReadLock();
570 jsr166 1.27 assertValid(lock, rs);
571 dl 1.4 lock.unlockRead(rs);
572     }});
573    
574     awaitTermination(t);
575     lock.unlockRead(s);
576     }
577    
578     /**
579 jsr166 1.27 * tryWriteLock fails when read locked
580 dl 1.4 */
581 jsr166 1.27 public void testTryWriteLockWhenReadLocked() {
582 dl 1.4 final StampedLock lock = new StampedLock();
583     long s = lock.readLock();
584     Thread t = newStartedThread(new CheckedRunnable() {
585     public void realRun() {
586 jsr166 1.27 threadAssertEquals(0L, lock.tryWriteLock());
587 dl 1.4 }});
588    
589     awaitTermination(t);
590     lock.unlockRead(s);
591     }
592    
593     /**
594 jsr166 1.27 * timed lock operations time out if lock not available
595 dl 1.4 */
596 jsr166 1.27 public void testTimedLock_Timeout() throws Exception {
597     ArrayList<Future<?>> futures = new ArrayList<>();
598    
599     // Write locked
600 dl 1.4 final StampedLock lock = new StampedLock();
601 jsr166 1.27 long stamp = lock.writeLock();
602     assertEquals(0L, lock.tryReadLock(0L, DAYS));
603     assertEquals(0L, lock.tryReadLock(Long.MIN_VALUE, DAYS));
604     assertFalse(lock.asReadLock().tryLock(0L, DAYS));
605     assertFalse(lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS));
606     assertEquals(0L, lock.tryWriteLock(0L, DAYS));
607     assertEquals(0L, lock.tryWriteLock(Long.MIN_VALUE, DAYS));
608     assertFalse(lock.asWriteLock().tryLock(0L, DAYS));
609     assertFalse(lock.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
610    
611     futures.add(cachedThreadPool.submit(new CheckedRunnable() {
612 dl 1.4 public void realRun() throws InterruptedException {
613     long startTime = System.nanoTime();
614 jsr166 1.27 assertEquals(0L, lock.tryWriteLock(timeoutMillis(), MILLISECONDS));
615     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
616     }}));
617 dl 1.4
618 jsr166 1.27 futures.add(cachedThreadPool.submit(new CheckedRunnable() {
619     public void realRun() throws InterruptedException {
620     long startTime = System.nanoTime();
621     assertEquals(0L, lock.tryReadLock(timeoutMillis(), MILLISECONDS));
622     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
623     }}));
624    
625     // Read locked
626     final StampedLock lock2 = new StampedLock();
627     long stamp2 = lock2.readLock();
628     assertEquals(0L, lock2.tryWriteLock(0L, DAYS));
629     assertEquals(0L, lock2.tryWriteLock(Long.MIN_VALUE, DAYS));
630     assertFalse(lock2.asWriteLock().tryLock(0L, DAYS));
631     assertFalse(lock2.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
632 dl 1.4
633 jsr166 1.27 futures.add(cachedThreadPool.submit(new CheckedRunnable() {
634 dl 1.4 public void realRun() throws InterruptedException {
635     long startTime = System.nanoTime();
636 jsr166 1.27 assertEquals(0L, lock2.tryWriteLock(timeoutMillis(), MILLISECONDS));
637     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
638     }}));
639    
640     for (Future<?> future : futures)
641     assertNull(future.get());
642 jsr166 1.7
643 jsr166 1.27 releaseWriteLock(lock, stamp);
644     releaseReadLock(lock2, stamp2);
645 dl 1.4 }
646    
647     /**
648 jsr166 1.27 * writeLockInterruptibly succeeds if unlocked
649 dl 1.4 */
650 jsr166 1.11 public void testWriteLockInterruptibly() throws InterruptedException {
651 dl 1.4 final StampedLock lock = new StampedLock();
652 jsr166 1.11 long s = lock.writeLockInterruptibly();
653     assertTrue(lock.isWriteLocked());
654     releaseWriteLock(lock, s);
655 dl 1.4 }
656    
657     /**
658 jsr166 1.27 * readLockInterruptibly succeeds if lock free
659 dl 1.4 */
660 jsr166 1.11 public void testReadLockInterruptibly() throws InterruptedException {
661 dl 1.4 final StampedLock lock = new StampedLock();
662 jsr166 1.27
663     long s = assertValid(lock, lock.readLockInterruptibly());
664     assertTrue(lock.isReadLocked());
665 jsr166 1.11 lock.unlockRead(s);
666 jsr166 1.12
667 jsr166 1.27 lock.asReadLock().lockInterruptibly();
668     assertTrue(lock.isReadLocked());
669     lock.asReadLock().unlock();
670 dl 1.4 }
671    
672     /**
673     * A serialized lock deserializes as unlocked
674     */
675     public void testSerialization() {
676     StampedLock lock = new StampedLock();
677     lock.writeLock();
678     StampedLock clone = serialClone(lock);
679     assertTrue(lock.isWriteLocked());
680     assertFalse(clone.isWriteLocked());
681     long s = clone.writeLock();
682     assertTrue(clone.isWriteLocked());
683     clone.unlockWrite(s);
684     assertFalse(clone.isWriteLocked());
685     }
686 dl 1.5
687 dl 1.4 /**
688     * toString indicates current lock state
689     */
690     public void testToString() {
691     StampedLock lock = new StampedLock();
692     assertTrue(lock.toString().contains("Unlocked"));
693     long s = lock.writeLock();
694     assertTrue(lock.toString().contains("Write-locked"));
695     lock.unlockWrite(s);
696     s = lock.readLock();
697     assertTrue(lock.toString().contains("Read-locks"));
698     }
699    
700     /**
701 jsr166 1.27 * tryOptimisticRead succeeds and validates if unlocked, fails if
702     * exclusively locked
703 dl 1.4 */
704 jsr166 1.11 public void testValidateOptimistic() throws InterruptedException {
705     StampedLock lock = new StampedLock();
706 jsr166 1.27
707     assertValid(lock, lock.tryOptimisticRead());
708    
709     for (Function<StampedLock, Long> writeLocker : writeLockers()) {
710     long s = assertValid(lock, writeLocker.apply(lock));
711     assertEquals(0L, lock.tryOptimisticRead());
712     releaseWriteLock(lock, s);
713     }
714    
715     for (Function<StampedLock, Long> readLocker : readLockers()) {
716     long s = assertValid(lock, readLocker.apply(lock));
717     long p = assertValid(lock, lock.tryOptimisticRead());
718     releaseReadLock(lock, s);
719     assertTrue(lock.validate(p));
720     }
721    
722     assertValid(lock, lock.tryOptimisticRead());
723 dl 1.4 }
724    
725     /**
726     * tryOptimisticRead stamp does not validate if a write lock intervenes
727     */
728     public void testValidateOptimisticWriteLocked() {
729 jsr166 1.27 final StampedLock lock = new StampedLock();
730     final long p = assertValid(lock, lock.tryOptimisticRead());
731     final long s = assertValid(lock, lock.writeLock());
732 dl 1.4 assertFalse(lock.validate(p));
733 jsr166 1.27 assertEquals(0L, lock.tryOptimisticRead());
734 dl 1.4 assertTrue(lock.validate(s));
735     lock.unlockWrite(s);
736     }
737    
738     /**
739     * tryOptimisticRead stamp does not validate if a write lock
740     * intervenes in another thread
741     */
742 jsr166 1.11 public void testValidateOptimisticWriteLocked2()
743     throws InterruptedException {
744 jsr166 1.32 final CountDownLatch locked = new CountDownLatch(1);
745 dl 1.4 final StampedLock lock = new StampedLock();
746 jsr166 1.27 final long p = assertValid(lock, lock.tryOptimisticRead());
747    
748 dl 1.4 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
749 jsr166 1.11 public void realRun() throws InterruptedException {
750     lock.writeLockInterruptibly();
751 jsr166 1.32 locked.countDown();
752 jsr166 1.11 lock.writeLockInterruptibly();
753     }});
754 jsr166 1.12
755 jsr166 1.34 await(locked);
756 jsr166 1.11 assertFalse(lock.validate(p));
757 jsr166 1.27 assertEquals(0L, lock.tryOptimisticRead());
758 jsr166 1.35 assertThreadBlocks(t, Thread.State.WAITING);
759 jsr166 1.11 t.interrupt();
760     awaitTermination(t);
761 jsr166 1.33 assertTrue(lock.isWriteLocked());
762 dl 1.4 }
763    
764     /**
765 jsr166 1.27 * tryConvertToOptimisticRead succeeds and validates if successfully locked
766 dl 1.4 */
767 jsr166 1.11 public void testTryConvertToOptimisticRead() throws InterruptedException {
768     StampedLock lock = new StampedLock();
769 jsr166 1.27 long s, p, q;
770 jsr166 1.19 assertEquals(0L, lock.tryConvertToOptimisticRead(0L));
771    
772 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
773 jsr166 1.19 assertEquals(s, lock.tryConvertToOptimisticRead(s));
774     assertTrue(lock.validate(s));
775    
776 jsr166 1.27 for (Function<StampedLock, Long> writeLocker : writeLockers()) {
777     s = assertValid(lock, writeLocker.apply(lock));
778     p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
779     assertFalse(lock.validate(s));
780     assertTrue(lock.validate(p));
781     assertUnlocked(lock);
782     }
783 jsr166 1.20
784 jsr166 1.27 for (Function<StampedLock, Long> readLocker : readLockers()) {
785     s = assertValid(lock, readLocker.apply(lock));
786     q = assertValid(lock, lock.tryOptimisticRead());
787     assertEquals(q, lock.tryConvertToOptimisticRead(q));
788     assertTrue(lock.validate(q));
789     assertTrue(lock.isReadLocked());
790     p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
791     assertTrue(lock.validate(p));
792     assertTrue(lock.validate(s));
793     assertUnlocked(lock);
794     assertEquals(q, lock.tryConvertToOptimisticRead(q));
795     assertTrue(lock.validate(q));
796     }
797 dl 1.4 }
798    
799     /**
800 jsr166 1.27 * tryConvertToReadLock succeeds for valid stamps
801 dl 1.4 */
802 jsr166 1.11 public void testTryConvertToReadLock() throws InterruptedException {
803     StampedLock lock = new StampedLock();
804     long s, p;
805 jsr166 1.22
806 jsr166 1.27 assertEquals(0L, lock.tryConvertToReadLock(0L));
807 jsr166 1.22
808 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
809     p = assertValid(lock, lock.tryConvertToReadLock(s));
810 jsr166 1.22 assertTrue(lock.isReadLocked());
811     assertEquals(1, lock.getReadLockCount());
812 jsr166 1.27 assertTrue(lock.validate(s));
813 jsr166 1.11 lock.unlockRead(p);
814 jsr166 1.22
815 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
816 jsr166 1.24 lock.readLock();
817 jsr166 1.27 p = assertValid(lock, lock.tryConvertToReadLock(s));
818 jsr166 1.24 assertTrue(lock.isReadLocked());
819     assertEquals(2, lock.getReadLockCount());
820     lock.unlockRead(p);
821     lock.unlockRead(p);
822 jsr166 1.27 assertUnlocked(lock);
823 jsr166 1.24
824 jsr166 1.27 for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
825     for (Function<StampedLock, Long> writeLocker : writeLockers()) {
826     s = assertValid(lock, writeLocker.apply(lock));
827     p = assertValid(lock, lock.tryConvertToReadLock(s));
828     assertFalse(lock.validate(s));
829     assertTrue(lock.isReadLocked());
830     assertEquals(1, lock.getReadLockCount());
831     readUnlocker.accept(lock, p);
832     }
833    
834     for (Function<StampedLock, Long> readLocker : readLockers()) {
835     s = assertValid(lock, readLocker.apply(lock));
836     assertEquals(s, lock.tryConvertToReadLock(s));
837     assertTrue(lock.validate(s));
838     assertTrue(lock.isReadLocked());
839     assertEquals(1, lock.getReadLockCount());
840     readUnlocker.accept(lock, s);
841     }
842     }
843 dl 1.4 }
844    
845     /**
846 jsr166 1.27 * tryConvertToWriteLock succeeds if lock available; fails if multiply read locked
847 dl 1.4 */
848 jsr166 1.11 public void testTryConvertToWriteLock() throws InterruptedException {
849     StampedLock lock = new StampedLock();
850     long s, p;
851 jsr166 1.21
852 jsr166 1.27 assertEquals(0L, lock.tryConvertToWriteLock(0L));
853 jsr166 1.21
854 jsr166 1.11 assertTrue((s = lock.tryOptimisticRead()) != 0L);
855     assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
856 jsr166 1.23 assertTrue(lock.isWriteLocked());
857 jsr166 1.11 lock.unlockWrite(p);
858 jsr166 1.21
859 jsr166 1.27 for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
860     for (Function<StampedLock, Long> writeLocker : writeLockers()) {
861     s = assertValid(lock, writeLocker.apply(lock));
862     assertEquals(s, lock.tryConvertToWriteLock(s));
863     assertTrue(lock.validate(s));
864     assertTrue(lock.isWriteLocked());
865     writeUnlocker.accept(lock, s);
866     }
867    
868     for (Function<StampedLock, Long> readLocker : readLockers()) {
869     s = assertValid(lock, readLocker.apply(lock));
870     p = assertValid(lock, lock.tryConvertToWriteLock(s));
871     assertFalse(lock.validate(s));
872     assertTrue(lock.validate(p));
873     assertTrue(lock.isWriteLocked());
874     writeUnlocker.accept(lock, p);
875     }
876     }
877 jsr166 1.21
878 jsr166 1.27 // failure if multiply read locked
879     for (Function<StampedLock, Long> readLocker : readLockers()) {
880     s = assertValid(lock, readLocker.apply(lock));
881     p = assertValid(lock, readLocker.apply(lock));
882     assertEquals(0L, lock.tryConvertToWriteLock(s));
883     assertTrue(lock.validate(s));
884     assertTrue(lock.validate(p));
885     assertEquals(2, lock.getReadLockCount());
886     lock.unlock(p);
887     lock.unlock(s);
888     assertUnlocked(lock);
889     }
890 dl 1.4 }
891    
892     /**
893     * asWriteLock can be locked and unlocked
894     */
895 jsr166 1.27 public void testAsWriteLock() throws Throwable {
896 dl 1.4 StampedLock sl = new StampedLock();
897     Lock lock = sl.asWriteLock();
898 jsr166 1.27 for (Action locker : lockLockers(lock)) {
899     locker.run();
900     assertTrue(sl.isWriteLocked());
901     assertFalse(sl.isReadLocked());
902     assertFalse(lock.tryLock());
903     lock.unlock();
904     assertUnlocked(sl);
905     }
906 dl 1.4 }
907    
908     /**
909     * asReadLock can be locked and unlocked
910     */
911 jsr166 1.27 public void testAsReadLock() throws Throwable {
912 dl 1.4 StampedLock sl = new StampedLock();
913     Lock lock = sl.asReadLock();
914 jsr166 1.27 for (Action locker : lockLockers(lock)) {
915     locker.run();
916     assertTrue(sl.isReadLocked());
917     assertFalse(sl.isWriteLocked());
918     assertEquals(1, sl.getReadLockCount());
919     locker.run();
920     assertTrue(sl.isReadLocked());
921     assertEquals(2, sl.getReadLockCount());
922     lock.unlock();
923     lock.unlock();
924     assertUnlocked(sl);
925     }
926 dl 1.4 }
927    
928     /**
929     * asReadWriteLock.writeLock can be locked and unlocked
930     */
931 jsr166 1.27 public void testAsReadWriteLockWriteLock() throws Throwable {
932 dl 1.4 StampedLock sl = new StampedLock();
933     Lock lock = sl.asReadWriteLock().writeLock();
934 jsr166 1.27 for (Action locker : lockLockers(lock)) {
935     locker.run();
936     assertTrue(sl.isWriteLocked());
937     assertFalse(sl.isReadLocked());
938     assertFalse(lock.tryLock());
939     lock.unlock();
940     assertUnlocked(sl);
941     }
942 dl 1.4 }
943    
944     /**
945     * asReadWriteLock.readLock can be locked and unlocked
946     */
947 jsr166 1.27 public void testAsReadWriteLockReadLock() throws Throwable {
948 dl 1.4 StampedLock sl = new StampedLock();
949     Lock lock = sl.asReadWriteLock().readLock();
950 jsr166 1.27 for (Action locker : lockLockers(lock)) {
951     locker.run();
952     assertTrue(sl.isReadLocked());
953     assertFalse(sl.isWriteLocked());
954     assertEquals(1, sl.getReadLockCount());
955     locker.run();
956     assertTrue(sl.isReadLocked());
957     assertEquals(2, sl.getReadLockCount());
958     lock.unlock();
959     lock.unlock();
960     assertUnlocked(sl);
961     }
962 dl 1.4 }
963 jsr166 1.1
964 jsr166 1.15 /**
965     * Lock.newCondition throws UnsupportedOperationException
966     */
967     public void testLockViewsDoNotSupportConditions() {
968     StampedLock sl = new StampedLock();
969     assertThrows(UnsupportedOperationException.class,
970     () -> sl.asWriteLock().newCondition(),
971     () -> sl.asReadLock().newCondition(),
972     () -> sl.asReadWriteLock().writeLock().newCondition(),
973     () -> sl.asReadWriteLock().readLock().newCondition());
974     }
975    
976 jsr166 1.16 /**
977     * Passing optimistic read stamps to unlock operations result in
978     * IllegalMonitorStateException
979     */
980     public void testCannotUnlockOptimisticReadStamps() {
981     Runnable[] actions = {
982     () -> {
983     StampedLock sl = new StampedLock();
984 jsr166 1.27 long stamp = assertValid(sl, sl.tryOptimisticRead());
985 jsr166 1.16 sl.unlockRead(stamp);
986     },
987     () -> {
988     StampedLock sl = new StampedLock();
989     long stamp = sl.tryOptimisticRead();
990     sl.unlock(stamp);
991     },
992    
993     () -> {
994     StampedLock sl = new StampedLock();
995     long stamp = sl.tryOptimisticRead();
996     sl.writeLock();
997     sl.unlock(stamp);
998     },
999     () -> {
1000     StampedLock sl = new StampedLock();
1001     sl.readLock();
1002 jsr166 1.27 long stamp = assertValid(sl, sl.tryOptimisticRead());
1003 jsr166 1.16 sl.unlockRead(stamp);
1004     },
1005     () -> {
1006     StampedLock sl = new StampedLock();
1007     sl.readLock();
1008 jsr166 1.27 long stamp = assertValid(sl, sl.tryOptimisticRead());
1009 jsr166 1.16 sl.unlock(stamp);
1010     },
1011    
1012     () -> {
1013     StampedLock sl = new StampedLock();
1014     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1015 jsr166 1.27 assertValid(sl, stamp);
1016 jsr166 1.16 sl.writeLock();
1017     sl.unlockWrite(stamp);
1018     },
1019     () -> {
1020     StampedLock sl = new StampedLock();
1021     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1022     sl.writeLock();
1023     sl.unlock(stamp);
1024     },
1025     () -> {
1026     StampedLock sl = new StampedLock();
1027     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1028     sl.readLock();
1029     sl.unlockRead(stamp);
1030     },
1031     () -> {
1032     StampedLock sl = new StampedLock();
1033     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1034     sl.readLock();
1035     sl.unlock(stamp);
1036     },
1037    
1038     () -> {
1039     StampedLock sl = new StampedLock();
1040     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1041 jsr166 1.27 assertValid(sl, stamp);
1042 jsr166 1.16 sl.writeLock();
1043     sl.unlockWrite(stamp);
1044     },
1045     () -> {
1046     StampedLock sl = new StampedLock();
1047     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1048     sl.writeLock();
1049     sl.unlock(stamp);
1050     },
1051     () -> {
1052     StampedLock sl = new StampedLock();
1053     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1054     sl.readLock();
1055     sl.unlockRead(stamp);
1056     },
1057     () -> {
1058     StampedLock sl = new StampedLock();
1059 jsr166 1.18 sl.readLock();
1060     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1061 jsr166 1.27 assertValid(sl, stamp);
1062 jsr166 1.18 sl.readLock();
1063     sl.unlockRead(stamp);
1064     },
1065     () -> {
1066     StampedLock sl = new StampedLock();
1067     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1068     sl.readLock();
1069     sl.unlock(stamp);
1070     },
1071     () -> {
1072     StampedLock sl = new StampedLock();
1073     sl.readLock();
1074 jsr166 1.16 long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1075     sl.readLock();
1076     sl.unlock(stamp);
1077     },
1078     };
1079 jsr166 1.17
1080 jsr166 1.16 assertThrows(IllegalMonitorStateException.class, actions);
1081     }
1082    
1083 jsr166 1.25 static long writeLockInterruptiblyUninterrupted(StampedLock sl) {
1084     try { return sl.writeLockInterruptibly(); }
1085     catch (InterruptedException ex) { throw new AssertionError(ex); }
1086     }
1087    
1088     static long tryWriteLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1089     try { return sl.tryWriteLock(time, unit); }
1090     catch (InterruptedException ex) { throw new AssertionError(ex); }
1091     }
1092    
1093 jsr166 1.26 static long readLockInterruptiblyUninterrupted(StampedLock sl) {
1094     try { return sl.readLockInterruptibly(); }
1095     catch (InterruptedException ex) { throw new AssertionError(ex); }
1096     }
1097    
1098     static long tryReadLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1099     try { return sl.tryReadLock(time, unit); }
1100     catch (InterruptedException ex) { throw new AssertionError(ex); }
1101     }
1102    
1103 jsr166 1.25 /**
1104 jsr166 1.27 * Invalid stamps result in IllegalMonitorStateException
1105 jsr166 1.25 */
1106 jsr166 1.27 public void testInvalidStampsThrowIllegalMonitorStateException() {
1107     final StampedLock sl = new StampedLock();
1108    
1109     assertThrows(IllegalMonitorStateException.class,
1110     () -> sl.unlockWrite(0L),
1111     () -> sl.unlockRead(0L),
1112     () -> sl.unlock(0L));
1113    
1114     final long optimisticStamp = sl.tryOptimisticRead();
1115     final long readStamp = sl.readLock();
1116     sl.unlockRead(readStamp);
1117     final long writeStamp = sl.writeLock();
1118     sl.unlockWrite(writeStamp);
1119     assertTrue(optimisticStamp != 0L && readStamp != 0L && writeStamp != 0L);
1120     final long[] noLongerValidStamps = { optimisticStamp, readStamp, writeStamp };
1121     final Runnable assertNoLongerValidStampsThrow = () -> {
1122     for (long noLongerValidStamp : noLongerValidStamps)
1123     assertThrows(IllegalMonitorStateException.class,
1124     () -> sl.unlockWrite(noLongerValidStamp),
1125     () -> sl.unlockRead(noLongerValidStamp),
1126     () -> sl.unlock(noLongerValidStamp));
1127     };
1128     assertNoLongerValidStampsThrow.run();
1129 jsr166 1.25
1130 jsr166 1.27 for (Function<StampedLock, Long> readLocker : readLockers())
1131     for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
1132     final long stamp = readLocker.apply(sl);
1133     assertValid(sl, stamp);
1134     assertNoLongerValidStampsThrow.run();
1135     assertThrows(IllegalMonitorStateException.class,
1136     () -> sl.unlockWrite(stamp),
1137     () -> sl.unlockRead(sl.tryOptimisticRead()),
1138     () -> sl.unlockRead(0L));
1139     readUnlocker.accept(sl, stamp);
1140     assertUnlocked(sl);
1141     assertNoLongerValidStampsThrow.run();
1142     }
1143 jsr166 1.26
1144 jsr166 1.27 for (Function<StampedLock, Long> writeLocker : writeLockers())
1145     for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
1146 jsr166 1.26 final long stamp = writeLocker.apply(sl);
1147 jsr166 1.27 assertValid(sl, stamp);
1148     assertNoLongerValidStampsThrow.run();
1149 jsr166 1.26 assertThrows(IllegalMonitorStateException.class,
1150 jsr166 1.27 () -> sl.unlockRead(stamp),
1151     () -> sl.unlockWrite(0L));
1152 jsr166 1.26 writeUnlocker.accept(sl, stamp);
1153 jsr166 1.27 assertUnlocked(sl);
1154     assertNoLongerValidStampsThrow.run();
1155 jsr166 1.26 }
1156     }
1157    
1158     /**
1159 jsr166 1.27 * Read locks can be very deeply nested
1160 jsr166 1.26 */
1161 jsr166 1.27 public void testDeeplyNestedReadLocks() {
1162     final StampedLock lock = new StampedLock();
1163     final int depth = 300;
1164     final long[] stamps = new long[depth];
1165     final List<Function<StampedLock, Long>> readLockers = readLockers();
1166     final List<BiConsumer<StampedLock, Long>> readUnlockers = readUnlockers();
1167     for (int i = 0; i < depth; i++) {
1168     Function<StampedLock, Long> readLocker
1169     = readLockers.get(i % readLockers.size());
1170     long stamp = readLocker.apply(lock);
1171     assertEquals(i + 1, lock.getReadLockCount());
1172     assertTrue(lock.isReadLocked());
1173     stamps[i] = stamp;
1174     }
1175     for (int i = 0; i < depth; i++) {
1176     BiConsumer<StampedLock, Long> readUnlocker
1177     = readUnlockers.get(i % readUnlockers.size());
1178     assertEquals(depth - i, lock.getReadLockCount());
1179     assertTrue(lock.isReadLocked());
1180     readUnlocker.accept(lock, stamps[depth - 1 - i]);
1181 jsr166 1.25 }
1182 jsr166 1.27 assertUnlocked(lock);
1183 jsr166 1.25 }
1184 jsr166 1.1 }