ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/StampedLockTest.java
Revision: 1.27
Committed: Wed Aug 10 17:05:13 2016 UTC (7 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.26: +583 -581 lines
Log Message:
more test scenarios

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