ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/StampedLockTest.java
Revision: 1.28
Committed: Wed Aug 24 22:22:39 2016 UTC (7 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.27: +0 -1 lines
Log Message:
fix imports

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     readLockers.add((sl) -> sl.readLock());
87     readLockers.add((sl) -> sl.tryReadLock());
88     readLockers.add((sl) -> readLockInterruptiblyUninterrupted(sl));
89     readLockers.add((sl) -> tryReadLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
90     readLockers.add((sl) -> tryReadLockUninterrupted(sl, 0L, DAYS));
91     readLockers.add((sl) -> sl.tryConvertToReadLock(sl.tryOptimisticRead()));
92     return readLockers;
93 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     writeLockers.add((sl) -> sl.writeLock());
108     writeLockers.add((sl) -> sl.tryWriteLock());
109     writeLockers.add((sl) -> writeLockInterruptiblyUninterrupted(sl));
110     writeLockers.add((sl) -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
111     writeLockers.add((sl) -> tryWriteLockUninterrupted(sl, 0L, DAYS));
112     writeLockers.add((sl) -> sl.tryConvertToWriteLock(sl.tryOptimisticRead()));
113     return writeLockers;
114 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.27 assertFalse(lock.validate(lock.tryWriteLock(0L, SECONDS)));
252 jsr166 1.11 assertFalse(lock.validate(lock.tryReadLock()));
253 jsr166 1.27 assertFalse(lock.validate(lock.tryReadLock(0L, SECONDS)));
254 jsr166 1.11 assertFalse(lock.validate(lock.tryOptimisticRead()));
255     lock.unlockWrite(s);
256 dl 1.4 }
257    
258 jsr166 1.27 void assertThrowInterruptedExceptionWhenPreInterrupted(Action[] actions) {
259     for (Action action : actions) {
260     Thread.currentThread().interrupt();
261     try {
262     action.run();
263     shouldThrow();
264     }
265     catch (InterruptedException success) {}
266     catch (Throwable fail) { threadUnexpectedException(fail); }
267     assertFalse(Thread.interrupted());
268     }
269     }
270    
271 dl 1.4 /**
272 jsr166 1.27 * interruptible operations throw InterruptedException when pre-interrupted
273 dl 1.4 */
274 jsr166 1.27 public void testInterruptibleOperationsThrowInterruptedExceptionWhenPreInterrupted() {
275 dl 1.4 final CountDownLatch running = new CountDownLatch(1);
276     final StampedLock lock = new StampedLock();
277 jsr166 1.12
278 jsr166 1.27 Action[] interruptibleLockActions = {
279     () -> lock.writeLockInterruptibly(),
280     () -> lock.tryWriteLock(Long.MIN_VALUE, DAYS),
281     () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
282     () -> lock.readLockInterruptibly(),
283     () -> lock.tryReadLock(Long.MIN_VALUE, DAYS),
284     () -> lock.tryReadLock(Long.MAX_VALUE, DAYS),
285     () -> lock.asWriteLock().lockInterruptibly(),
286     () -> lock.asWriteLock().tryLock(0L, DAYS),
287     () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
288     () -> lock.asReadLock().lockInterruptibly(),
289     () -> lock.asReadLock().tryLock(0L, DAYS),
290     () -> lock.asReadLock().tryLock(Long.MAX_VALUE, DAYS),
291     };
292     shuffle(interruptibleLockActions);
293    
294     assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
295     {
296     long s = lock.writeLock();
297     assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
298     lock.unlockWrite(s);
299     }
300     {
301     long s = lock.readLock();
302     assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
303     lock.unlockRead(s);
304     }
305     }
306    
307     void assertThrowInterruptedExceptionWhenInterrupted(Action[] actions) {
308     int n = actions.length;
309     Future<?>[] futures = new Future<?>[n];
310     CountDownLatch threadsStarted = new CountDownLatch(n);
311     CountDownLatch done = new CountDownLatch(n);
312    
313     for (int i = 0; i < n; i++) {
314     Action action = actions[i];
315     futures[i] = cachedThreadPool.submit(new CheckedRunnable() {
316     public void realRun() throws Throwable {
317     threadsStarted.countDown();
318     try {
319     action.run();
320     shouldThrow();
321     }
322     catch (InterruptedException success) {}
323     catch (Throwable fail) { threadUnexpectedException(fail); }
324     assertFalse(Thread.interrupted());
325     done.countDown();
326     }});
327     }
328    
329     await(threadsStarted);
330     assertEquals(n, done.getCount());
331     for (Future<?> future : futures) // Interrupt all the tasks
332     future.cancel(true);
333     await(done);
334 dl 1.4 }
335    
336     /**
337 jsr166 1.27 * interruptible operations throw InterruptedException when write locked and interrupted
338 dl 1.4 */
339 jsr166 1.27 public void testInterruptibleOperationsThrowInterruptedExceptionWriteLockedInterrupted() {
340 dl 1.4 final CountDownLatch running = new CountDownLatch(1);
341     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 CountDownLatch running = new CountDownLatch(1);
364     final StampedLock lock = new StampedLock();
365 jsr166 1.27 long s = lock.readLock();
366    
367     Action[] interruptibleLockBlockingActions = {
368     () -> lock.writeLockInterruptibly(),
369     () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
370     () -> lock.asWriteLock().lockInterruptibly(),
371     () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
372     };
373     shuffle(interruptibleLockBlockingActions);
374 jsr166 1.12
375 jsr166 1.27 assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions);
376 dl 1.4 }
377    
378     /**
379 jsr166 1.27 * Non-interruptible operations ignore and preserve interrupt status
380 dl 1.4 */
381 jsr166 1.27 public void testNonInterruptibleOperationsIgnoreInterrupts() {
382 dl 1.4 final StampedLock lock = new StampedLock();
383 jsr166 1.27 Thread.currentThread().interrupt();
384    
385     for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
386     long s = assertValid(lock, lock.readLock());
387     readUnlocker.accept(lock, s);
388     s = assertValid(lock, lock.tryReadLock());
389     readUnlocker.accept(lock, s);
390     }
391    
392     lock.asReadLock().lock();
393     lock.asReadLock().unlock();
394    
395     for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
396     long s = assertValid(lock, lock.writeLock());
397     writeUnlocker.accept(lock, s);
398     s = assertValid(lock, lock.tryWriteLock());
399     writeUnlocker.accept(lock, s);
400     }
401    
402     lock.asWriteLock().lock();
403     lock.asWriteLock().unlock();
404 jsr166 1.12
405 jsr166 1.27 assertTrue(Thread.interrupted());
406 dl 1.4 }
407    
408     /**
409     * tryWriteLock on an unlocked lock succeeds
410     */
411 jsr166 1.27 public void testTryWriteLock() {
412 dl 1.4 final StampedLock lock = new StampedLock();
413     long s = lock.tryWriteLock();
414     assertTrue(s != 0L);
415     assertTrue(lock.isWriteLocked());
416 jsr166 1.27 assertEquals(0L, lock.tryWriteLock());
417 dl 1.4 releaseWriteLock(lock, s);
418     }
419    
420     /**
421     * tryWriteLock fails if locked
422     */
423 jsr166 1.27 public void testTryWriteLockWhenLocked() {
424 dl 1.4 final StampedLock lock = new StampedLock();
425     long s = lock.writeLock();
426     Thread t = newStartedThread(new CheckedRunnable() {
427     public void realRun() {
428 jsr166 1.27 assertEquals(0L, lock.tryWriteLock());
429 dl 1.4 }});
430 jsr166 1.12
431 jsr166 1.27 assertEquals(0L, lock.tryWriteLock());
432 dl 1.4 awaitTermination(t);
433     releaseWriteLock(lock, s);
434     }
435    
436     /**
437     * tryReadLock fails if write-locked
438     */
439 jsr166 1.27 public void testTryReadLockWhenLocked() {
440 dl 1.4 final StampedLock lock = new StampedLock();
441     long s = lock.writeLock();
442     Thread t = newStartedThread(new CheckedRunnable() {
443     public void realRun() {
444 jsr166 1.27 assertEquals(0L, lock.tryReadLock());
445 dl 1.4 }});
446 jsr166 1.12
447 jsr166 1.27 assertEquals(0L, lock.tryReadLock());
448 dl 1.4 awaitTermination(t);
449     releaseWriteLock(lock, s);
450     }
451    
452     /**
453     * Multiple threads can hold a read lock when not write-locked
454     */
455     public void testMultipleReadLocks() {
456     final StampedLock lock = new StampedLock();
457     final long s = lock.readLock();
458     Thread t = newStartedThread(new CheckedRunnable() {
459     public void realRun() throws InterruptedException {
460     long s2 = lock.tryReadLock();
461 jsr166 1.27 assertValid(lock, s2);
462 dl 1.4 lock.unlockRead(s2);
463     long s3 = lock.tryReadLock(LONG_DELAY_MS, MILLISECONDS);
464 jsr166 1.27 assertValid(lock, s3);
465 dl 1.4 lock.unlockRead(s3);
466     long s4 = lock.readLock();
467 jsr166 1.27 assertValid(lock, s4);
468 dl 1.4 lock.unlockRead(s4);
469 jsr166 1.27 lock.asReadLock().lock();
470     lock.asReadLock().unlock();
471     lock.asReadLock().lockInterruptibly();
472     lock.asReadLock().unlock();
473     lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS);
474     lock.asReadLock().unlock();
475 dl 1.4 }});
476 jsr166 1.12
477 dl 1.4 awaitTermination(t);
478     lock.unlockRead(s);
479     }
480    
481     /**
482     * A writelock succeeds only after a reading thread unlocks
483     */
484 jsr166 1.11 public void testWriteAfterReadLock() throws InterruptedException {
485 dl 1.4 final CountDownLatch running = new CountDownLatch(1);
486     final StampedLock lock = new StampedLock();
487     long rs = lock.readLock();
488     Thread t = newStartedThread(new CheckedRunnable() {
489     public void realRun() {
490     running.countDown();
491     long s = lock.writeLock();
492     lock.unlockWrite(s);
493     }});
494 jsr166 1.12
495 jsr166 1.11 running.await();
496 jsr166 1.27 waitForThreadToEnterWaitState(t, MEDIUM_DELAY_MS);
497 jsr166 1.11 assertFalse(lock.isWriteLocked());
498     lock.unlockRead(rs);
499     awaitTermination(t);
500     assertFalse(lock.isWriteLocked());
501 dl 1.4 }
502    
503     /**
504     * A writelock succeeds only after reading threads unlock
505     */
506     public void testWriteAfterMultipleReadLocks() {
507     final StampedLock lock = new StampedLock();
508     long s = lock.readLock();
509     Thread t1 = newStartedThread(new CheckedRunnable() {
510     public void realRun() {
511     long rs = lock.readLock();
512     lock.unlockRead(rs);
513     }});
514 jsr166 1.12
515 dl 1.4 awaitTermination(t1);
516    
517     Thread t2 = newStartedThread(new CheckedRunnable() {
518     public void realRun() {
519     long ws = lock.writeLock();
520     lock.unlockWrite(ws);
521     }});
522 jsr166 1.12
523 jsr166 1.27 assertTrue(lock.isReadLocked());
524 dl 1.4 assertFalse(lock.isWriteLocked());
525     lock.unlockRead(s);
526     awaitTermination(t2);
527     assertFalse(lock.isWriteLocked());
528     }
529    
530     /**
531     * Readlocks succeed only after a writing thread unlocks
532     */
533     public void testReadAfterWriteLock() {
534     final StampedLock lock = new StampedLock();
535 jsr166 1.27 final CountDownLatch threadsStarted = new CountDownLatch(2);
536 dl 1.4 final long s = lock.writeLock();
537     Thread t1 = newStartedThread(new CheckedRunnable() {
538     public void realRun() {
539 jsr166 1.27 threadsStarted.countDown();
540 dl 1.4 long rs = lock.readLock();
541     lock.unlockRead(rs);
542     }});
543     Thread t2 = newStartedThread(new CheckedRunnable() {
544     public void realRun() {
545 jsr166 1.27 threadsStarted.countDown();
546 dl 1.4 long rs = lock.readLock();
547     lock.unlockRead(rs);
548     }});
549    
550 jsr166 1.27 await(threadsStarted);
551     waitForThreadToEnterWaitState(t1, MEDIUM_DELAY_MS);
552     waitForThreadToEnterWaitState(t2, MEDIUM_DELAY_MS);
553 dl 1.4 releaseWriteLock(lock, s);
554     awaitTermination(t1);
555     awaitTermination(t2);
556     }
557    
558     /**
559 jsr166 1.27 * tryReadLock succeeds if read locked but not write locked
560 dl 1.4 */
561     public void testTryLockWhenReadLocked() {
562     final StampedLock lock = new StampedLock();
563     long s = lock.readLock();
564     Thread t = newStartedThread(new CheckedRunnable() {
565     public void realRun() {
566     long rs = lock.tryReadLock();
567 jsr166 1.27 assertValid(lock, rs);
568 dl 1.4 lock.unlockRead(rs);
569     }});
570    
571     awaitTermination(t);
572     lock.unlockRead(s);
573     }
574    
575     /**
576 jsr166 1.27 * tryWriteLock fails when read locked
577 dl 1.4 */
578 jsr166 1.27 public void testTryWriteLockWhenReadLocked() {
579 dl 1.4 final StampedLock lock = new StampedLock();
580     long s = lock.readLock();
581     Thread t = newStartedThread(new CheckedRunnable() {
582     public void realRun() {
583 jsr166 1.27 threadAssertEquals(0L, lock.tryWriteLock());
584 dl 1.4 }});
585    
586     awaitTermination(t);
587     lock.unlockRead(s);
588     }
589    
590     /**
591 jsr166 1.27 * timed lock operations time out if lock not available
592 dl 1.4 */
593 jsr166 1.27 public void testTimedLock_Timeout() throws Exception {
594     ArrayList<Future<?>> futures = new ArrayList<>();
595    
596     // Write locked
597 dl 1.4 final StampedLock lock = new StampedLock();
598 jsr166 1.27 long stamp = lock.writeLock();
599     assertEquals(0L, lock.tryReadLock(0L, DAYS));
600     assertEquals(0L, lock.tryReadLock(Long.MIN_VALUE, DAYS));
601     assertFalse(lock.asReadLock().tryLock(0L, DAYS));
602     assertFalse(lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS));
603     assertEquals(0L, lock.tryWriteLock(0L, DAYS));
604     assertEquals(0L, lock.tryWriteLock(Long.MIN_VALUE, DAYS));
605     assertFalse(lock.asWriteLock().tryLock(0L, DAYS));
606     assertFalse(lock.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
607    
608     futures.add(cachedThreadPool.submit(new CheckedRunnable() {
609 dl 1.4 public void realRun() throws InterruptedException {
610     long startTime = System.nanoTime();
611 jsr166 1.27 assertEquals(0L, lock.tryWriteLock(timeoutMillis(), MILLISECONDS));
612     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
613     }}));
614 dl 1.4
615 jsr166 1.27 futures.add(cachedThreadPool.submit(new CheckedRunnable() {
616     public void realRun() throws InterruptedException {
617     long startTime = System.nanoTime();
618     assertEquals(0L, lock.tryReadLock(timeoutMillis(), MILLISECONDS));
619     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
620     }}));
621    
622     // Read locked
623     final StampedLock lock2 = new StampedLock();
624     long stamp2 = lock2.readLock();
625     assertEquals(0L, lock2.tryWriteLock(0L, DAYS));
626     assertEquals(0L, lock2.tryWriteLock(Long.MIN_VALUE, DAYS));
627     assertFalse(lock2.asWriteLock().tryLock(0L, DAYS));
628     assertFalse(lock2.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
629 dl 1.4
630 jsr166 1.27 futures.add(cachedThreadPool.submit(new CheckedRunnable() {
631 dl 1.4 public void realRun() throws InterruptedException {
632     long startTime = System.nanoTime();
633 jsr166 1.27 assertEquals(0L, lock2.tryWriteLock(timeoutMillis(), MILLISECONDS));
634     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
635     }}));
636    
637     for (Future<?> future : futures)
638     assertNull(future.get());
639 jsr166 1.7
640 jsr166 1.27 releaseWriteLock(lock, stamp);
641     releaseReadLock(lock2, stamp2);
642 dl 1.4 }
643    
644     /**
645 jsr166 1.27 * writeLockInterruptibly succeeds if unlocked
646 dl 1.4 */
647 jsr166 1.11 public void testWriteLockInterruptibly() throws InterruptedException {
648 dl 1.4 final StampedLock lock = new StampedLock();
649 jsr166 1.11 long s = lock.writeLockInterruptibly();
650     assertTrue(lock.isWriteLocked());
651     releaseWriteLock(lock, s);
652 dl 1.4 }
653    
654     /**
655 jsr166 1.27 * readLockInterruptibly succeeds if lock free
656 dl 1.4 */
657 jsr166 1.11 public void testReadLockInterruptibly() throws InterruptedException {
658 dl 1.4 final StampedLock lock = new StampedLock();
659 jsr166 1.27
660     long s = assertValid(lock, lock.readLockInterruptibly());
661     assertTrue(lock.isReadLocked());
662 jsr166 1.11 lock.unlockRead(s);
663 jsr166 1.12
664 jsr166 1.27 lock.asReadLock().lockInterruptibly();
665     assertTrue(lock.isReadLocked());
666     lock.asReadLock().unlock();
667 dl 1.4 }
668    
669     /**
670     * A serialized lock deserializes as unlocked
671     */
672     public void testSerialization() {
673     StampedLock lock = new StampedLock();
674     lock.writeLock();
675     StampedLock clone = serialClone(lock);
676     assertTrue(lock.isWriteLocked());
677     assertFalse(clone.isWriteLocked());
678     long s = clone.writeLock();
679     assertTrue(clone.isWriteLocked());
680     clone.unlockWrite(s);
681     assertFalse(clone.isWriteLocked());
682     }
683 dl 1.5
684 dl 1.4 /**
685     * toString indicates current lock state
686     */
687     public void testToString() {
688     StampedLock lock = new StampedLock();
689     assertTrue(lock.toString().contains("Unlocked"));
690     long s = lock.writeLock();
691     assertTrue(lock.toString().contains("Write-locked"));
692     lock.unlockWrite(s);
693     s = lock.readLock();
694     assertTrue(lock.toString().contains("Read-locks"));
695     }
696    
697     /**
698 jsr166 1.27 * tryOptimisticRead succeeds and validates if unlocked, fails if
699     * exclusively locked
700 dl 1.4 */
701 jsr166 1.11 public void testValidateOptimistic() throws InterruptedException {
702     StampedLock lock = new StampedLock();
703 jsr166 1.27
704     assertValid(lock, lock.tryOptimisticRead());
705    
706     for (Function<StampedLock, Long> writeLocker : writeLockers()) {
707     long s = assertValid(lock, writeLocker.apply(lock));
708     assertEquals(0L, lock.tryOptimisticRead());
709     releaseWriteLock(lock, s);
710     }
711    
712     for (Function<StampedLock, Long> readLocker : readLockers()) {
713     long s = assertValid(lock, readLocker.apply(lock));
714     long p = assertValid(lock, lock.tryOptimisticRead());
715     releaseReadLock(lock, s);
716     assertTrue(lock.validate(p));
717     }
718    
719     assertValid(lock, lock.tryOptimisticRead());
720 dl 1.4 }
721    
722     /**
723     * tryOptimisticRead stamp does not validate if a write lock intervenes
724     */
725     public void testValidateOptimisticWriteLocked() {
726 jsr166 1.27 final StampedLock lock = new StampedLock();
727     final long p = assertValid(lock, lock.tryOptimisticRead());
728     final long s = assertValid(lock, lock.writeLock());
729 dl 1.4 assertFalse(lock.validate(p));
730 jsr166 1.27 assertEquals(0L, lock.tryOptimisticRead());
731 dl 1.4 assertTrue(lock.validate(s));
732     lock.unlockWrite(s);
733     }
734    
735     /**
736     * tryOptimisticRead stamp does not validate if a write lock
737     * intervenes in another thread
738     */
739 jsr166 1.11 public void testValidateOptimisticWriteLocked2()
740     throws InterruptedException {
741 dl 1.4 final CountDownLatch running = new CountDownLatch(1);
742     final StampedLock lock = new StampedLock();
743 jsr166 1.27 final long p = assertValid(lock, lock.tryOptimisticRead());
744    
745 dl 1.4 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
746 jsr166 1.11 public void realRun() throws InterruptedException {
747     lock.writeLockInterruptibly();
748     running.countDown();
749     lock.writeLockInterruptibly();
750     }});
751 jsr166 1.12
752 jsr166 1.11 running.await();
753     assertFalse(lock.validate(p));
754 jsr166 1.27 assertEquals(0L, lock.tryOptimisticRead());
755 jsr166 1.11 t.interrupt();
756     awaitTermination(t);
757 dl 1.4 }
758    
759     /**
760 jsr166 1.27 * tryConvertToOptimisticRead succeeds and validates if successfully locked
761 dl 1.4 */
762 jsr166 1.11 public void testTryConvertToOptimisticRead() throws InterruptedException {
763     StampedLock lock = new StampedLock();
764 jsr166 1.27 long s, p, q;
765 jsr166 1.19 assertEquals(0L, lock.tryConvertToOptimisticRead(0L));
766    
767 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
768 jsr166 1.19 assertEquals(s, lock.tryConvertToOptimisticRead(s));
769     assertTrue(lock.validate(s));
770    
771 jsr166 1.27 for (Function<StampedLock, Long> writeLocker : writeLockers()) {
772     s = assertValid(lock, writeLocker.apply(lock));
773     p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
774     assertFalse(lock.validate(s));
775     assertTrue(lock.validate(p));
776     assertUnlocked(lock);
777     }
778 jsr166 1.20
779 jsr166 1.27 for (Function<StampedLock, Long> readLocker : readLockers()) {
780     s = assertValid(lock, readLocker.apply(lock));
781     q = assertValid(lock, lock.tryOptimisticRead());
782     assertEquals(q, lock.tryConvertToOptimisticRead(q));
783     assertTrue(lock.validate(q));
784     assertTrue(lock.isReadLocked());
785     p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
786     assertTrue(lock.validate(p));
787     assertTrue(lock.validate(s));
788     assertUnlocked(lock);
789     assertEquals(q, lock.tryConvertToOptimisticRead(q));
790     assertTrue(lock.validate(q));
791     }
792 dl 1.4 }
793    
794     /**
795 jsr166 1.27 * tryConvertToReadLock succeeds for valid stamps
796 dl 1.4 */
797 jsr166 1.11 public void testTryConvertToReadLock() throws InterruptedException {
798     StampedLock lock = new StampedLock();
799     long s, p;
800 jsr166 1.22
801 jsr166 1.27 assertEquals(0L, lock.tryConvertToReadLock(0L));
802 jsr166 1.22
803 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
804     p = assertValid(lock, lock.tryConvertToReadLock(s));
805 jsr166 1.22 assertTrue(lock.isReadLocked());
806     assertEquals(1, lock.getReadLockCount());
807 jsr166 1.27 assertTrue(lock.validate(s));
808 jsr166 1.11 lock.unlockRead(p);
809 jsr166 1.22
810 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
811 jsr166 1.24 lock.readLock();
812 jsr166 1.27 p = assertValid(lock, lock.tryConvertToReadLock(s));
813 jsr166 1.24 assertTrue(lock.isReadLocked());
814     assertEquals(2, lock.getReadLockCount());
815     lock.unlockRead(p);
816     lock.unlockRead(p);
817 jsr166 1.27 assertUnlocked(lock);
818 jsr166 1.24
819 jsr166 1.27 for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
820     for (Function<StampedLock, Long> writeLocker : writeLockers()) {
821     s = assertValid(lock, writeLocker.apply(lock));
822     p = assertValid(lock, lock.tryConvertToReadLock(s));
823     assertFalse(lock.validate(s));
824     assertTrue(lock.isReadLocked());
825     assertEquals(1, lock.getReadLockCount());
826     readUnlocker.accept(lock, p);
827     }
828    
829     for (Function<StampedLock, Long> readLocker : readLockers()) {
830     s = assertValid(lock, readLocker.apply(lock));
831     assertEquals(s, lock.tryConvertToReadLock(s));
832     assertTrue(lock.validate(s));
833     assertTrue(lock.isReadLocked());
834     assertEquals(1, lock.getReadLockCount());
835     readUnlocker.accept(lock, s);
836     }
837     }
838 dl 1.4 }
839    
840     /**
841 jsr166 1.27 * tryConvertToWriteLock succeeds if lock available; fails if multiply read locked
842 dl 1.4 */
843 jsr166 1.11 public void testTryConvertToWriteLock() throws InterruptedException {
844     StampedLock lock = new StampedLock();
845     long s, p;
846 jsr166 1.21
847 jsr166 1.27 assertEquals(0L, lock.tryConvertToWriteLock(0L));
848 jsr166 1.21
849 jsr166 1.11 assertTrue((s = lock.tryOptimisticRead()) != 0L);
850     assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
851 jsr166 1.23 assertTrue(lock.isWriteLocked());
852 jsr166 1.11 lock.unlockWrite(p);
853 jsr166 1.21
854 jsr166 1.27 for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
855     for (Function<StampedLock, Long> writeLocker : writeLockers()) {
856     s = assertValid(lock, writeLocker.apply(lock));
857     assertEquals(s, lock.tryConvertToWriteLock(s));
858     assertTrue(lock.validate(s));
859     assertTrue(lock.isWriteLocked());
860     writeUnlocker.accept(lock, s);
861     }
862    
863     for (Function<StampedLock, Long> readLocker : readLockers()) {
864     s = assertValid(lock, readLocker.apply(lock));
865     p = assertValid(lock, lock.tryConvertToWriteLock(s));
866     assertFalse(lock.validate(s));
867     assertTrue(lock.validate(p));
868     assertTrue(lock.isWriteLocked());
869     writeUnlocker.accept(lock, p);
870     }
871     }
872 jsr166 1.21
873 jsr166 1.27 // failure if multiply read locked
874     for (Function<StampedLock, Long> readLocker : readLockers()) {
875     s = assertValid(lock, readLocker.apply(lock));
876     p = assertValid(lock, readLocker.apply(lock));
877     assertEquals(0L, lock.tryConvertToWriteLock(s));
878     assertTrue(lock.validate(s));
879     assertTrue(lock.validate(p));
880     assertEquals(2, lock.getReadLockCount());
881     lock.unlock(p);
882     lock.unlock(s);
883     assertUnlocked(lock);
884     }
885 dl 1.4 }
886    
887     /**
888     * asWriteLock can be locked and unlocked
889     */
890 jsr166 1.27 public void testAsWriteLock() throws Throwable {
891 dl 1.4 StampedLock sl = new StampedLock();
892     Lock lock = sl.asWriteLock();
893 jsr166 1.27 for (Action locker : lockLockers(lock)) {
894     locker.run();
895     assertTrue(sl.isWriteLocked());
896     assertFalse(sl.isReadLocked());
897     assertFalse(lock.tryLock());
898     lock.unlock();
899     assertUnlocked(sl);
900     }
901 dl 1.4 }
902    
903     /**
904     * asReadLock can be locked and unlocked
905     */
906 jsr166 1.27 public void testAsReadLock() throws Throwable {
907 dl 1.4 StampedLock sl = new StampedLock();
908     Lock lock = sl.asReadLock();
909 jsr166 1.27 for (Action locker : lockLockers(lock)) {
910     locker.run();
911     assertTrue(sl.isReadLocked());
912     assertFalse(sl.isWriteLocked());
913     assertEquals(1, sl.getReadLockCount());
914     locker.run();
915     assertTrue(sl.isReadLocked());
916     assertEquals(2, sl.getReadLockCount());
917     lock.unlock();
918     lock.unlock();
919     assertUnlocked(sl);
920     }
921 dl 1.4 }
922    
923     /**
924     * asReadWriteLock.writeLock can be locked and unlocked
925     */
926 jsr166 1.27 public void testAsReadWriteLockWriteLock() throws Throwable {
927 dl 1.4 StampedLock sl = new StampedLock();
928     Lock lock = sl.asReadWriteLock().writeLock();
929 jsr166 1.27 for (Action locker : lockLockers(lock)) {
930     locker.run();
931     assertTrue(sl.isWriteLocked());
932     assertFalse(sl.isReadLocked());
933     assertFalse(lock.tryLock());
934     lock.unlock();
935     assertUnlocked(sl);
936     }
937 dl 1.4 }
938    
939     /**
940     * asReadWriteLock.readLock can be locked and unlocked
941     */
942 jsr166 1.27 public void testAsReadWriteLockReadLock() throws Throwable {
943 dl 1.4 StampedLock sl = new StampedLock();
944     Lock lock = sl.asReadWriteLock().readLock();
945 jsr166 1.27 for (Action locker : lockLockers(lock)) {
946     locker.run();
947     assertTrue(sl.isReadLocked());
948     assertFalse(sl.isWriteLocked());
949     assertEquals(1, sl.getReadLockCount());
950     locker.run();
951     assertTrue(sl.isReadLocked());
952     assertEquals(2, sl.getReadLockCount());
953     lock.unlock();
954     lock.unlock();
955     assertUnlocked(sl);
956     }
957 dl 1.4 }
958 jsr166 1.1
959 jsr166 1.15 /**
960     * Lock.newCondition throws UnsupportedOperationException
961     */
962     public void testLockViewsDoNotSupportConditions() {
963     StampedLock sl = new StampedLock();
964     assertThrows(UnsupportedOperationException.class,
965     () -> sl.asWriteLock().newCondition(),
966     () -> sl.asReadLock().newCondition(),
967     () -> sl.asReadWriteLock().writeLock().newCondition(),
968     () -> sl.asReadWriteLock().readLock().newCondition());
969     }
970    
971 jsr166 1.16 /**
972     * Passing optimistic read stamps to unlock operations result in
973     * IllegalMonitorStateException
974     */
975     public void testCannotUnlockOptimisticReadStamps() {
976     Runnable[] actions = {
977     () -> {
978     StampedLock sl = new StampedLock();
979 jsr166 1.27 long stamp = assertValid(sl, sl.tryOptimisticRead());
980 jsr166 1.16 sl.unlockRead(stamp);
981     },
982     () -> {
983     StampedLock sl = new StampedLock();
984     long stamp = sl.tryOptimisticRead();
985     sl.unlock(stamp);
986     },
987    
988     () -> {
989     StampedLock sl = new StampedLock();
990     long stamp = sl.tryOptimisticRead();
991     sl.writeLock();
992     sl.unlock(stamp);
993     },
994     () -> {
995     StampedLock sl = new StampedLock();
996     sl.readLock();
997 jsr166 1.27 long stamp = assertValid(sl, sl.tryOptimisticRead());
998 jsr166 1.16 sl.unlockRead(stamp);
999     },
1000     () -> {
1001     StampedLock sl = new StampedLock();
1002     sl.readLock();
1003 jsr166 1.27 long stamp = assertValid(sl, sl.tryOptimisticRead());
1004 jsr166 1.16 sl.unlock(stamp);
1005     },
1006    
1007     () -> {
1008     StampedLock sl = new StampedLock();
1009     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1010 jsr166 1.27 assertValid(sl, stamp);
1011 jsr166 1.16 sl.writeLock();
1012     sl.unlockWrite(stamp);
1013     },
1014     () -> {
1015     StampedLock sl = new StampedLock();
1016     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1017     sl.writeLock();
1018     sl.unlock(stamp);
1019     },
1020     () -> {
1021     StampedLock sl = new StampedLock();
1022     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1023     sl.readLock();
1024     sl.unlockRead(stamp);
1025     },
1026     () -> {
1027     StampedLock sl = new StampedLock();
1028     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1029     sl.readLock();
1030     sl.unlock(stamp);
1031     },
1032    
1033     () -> {
1034     StampedLock sl = new StampedLock();
1035     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1036 jsr166 1.27 assertValid(sl, stamp);
1037 jsr166 1.16 sl.writeLock();
1038     sl.unlockWrite(stamp);
1039     },
1040     () -> {
1041     StampedLock sl = new StampedLock();
1042     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1043     sl.writeLock();
1044     sl.unlock(stamp);
1045     },
1046     () -> {
1047     StampedLock sl = new StampedLock();
1048     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1049     sl.readLock();
1050     sl.unlockRead(stamp);
1051     },
1052     () -> {
1053     StampedLock sl = new StampedLock();
1054 jsr166 1.18 sl.readLock();
1055     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1056 jsr166 1.27 assertValid(sl, stamp);
1057 jsr166 1.18 sl.readLock();
1058     sl.unlockRead(stamp);
1059     },
1060     () -> {
1061     StampedLock sl = new StampedLock();
1062     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1063     sl.readLock();
1064     sl.unlock(stamp);
1065     },
1066     () -> {
1067     StampedLock sl = new StampedLock();
1068     sl.readLock();
1069 jsr166 1.16 long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1070     sl.readLock();
1071     sl.unlock(stamp);
1072     },
1073     };
1074 jsr166 1.17
1075 jsr166 1.16 assertThrows(IllegalMonitorStateException.class, actions);
1076     }
1077    
1078 jsr166 1.25 static long writeLockInterruptiblyUninterrupted(StampedLock sl) {
1079     try { return sl.writeLockInterruptibly(); }
1080     catch (InterruptedException ex) { throw new AssertionError(ex); }
1081     }
1082    
1083     static long tryWriteLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1084     try { return sl.tryWriteLock(time, unit); }
1085     catch (InterruptedException ex) { throw new AssertionError(ex); }
1086     }
1087    
1088 jsr166 1.26 static long readLockInterruptiblyUninterrupted(StampedLock sl) {
1089     try { return sl.readLockInterruptibly(); }
1090     catch (InterruptedException ex) { throw new AssertionError(ex); }
1091     }
1092    
1093     static long tryReadLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1094     try { return sl.tryReadLock(time, unit); }
1095     catch (InterruptedException ex) { throw new AssertionError(ex); }
1096     }
1097    
1098 jsr166 1.25 /**
1099 jsr166 1.27 * Invalid stamps result in IllegalMonitorStateException
1100 jsr166 1.25 */
1101 jsr166 1.27 public void testInvalidStampsThrowIllegalMonitorStateException() {
1102     final StampedLock sl = new StampedLock();
1103    
1104     assertThrows(IllegalMonitorStateException.class,
1105     () -> sl.unlockWrite(0L),
1106     () -> sl.unlockRead(0L),
1107     () -> sl.unlock(0L));
1108    
1109     final long optimisticStamp = sl.tryOptimisticRead();
1110     final long readStamp = sl.readLock();
1111     sl.unlockRead(readStamp);
1112     final long writeStamp = sl.writeLock();
1113     sl.unlockWrite(writeStamp);
1114     assertTrue(optimisticStamp != 0L && readStamp != 0L && writeStamp != 0L);
1115     final long[] noLongerValidStamps = { optimisticStamp, readStamp, writeStamp };
1116     final Runnable assertNoLongerValidStampsThrow = () -> {
1117     for (long noLongerValidStamp : noLongerValidStamps)
1118     assertThrows(IllegalMonitorStateException.class,
1119     () -> sl.unlockWrite(noLongerValidStamp),
1120     () -> sl.unlockRead(noLongerValidStamp),
1121     () -> sl.unlock(noLongerValidStamp));
1122     };
1123     assertNoLongerValidStampsThrow.run();
1124 jsr166 1.25
1125 jsr166 1.27 for (Function<StampedLock, Long> readLocker : readLockers())
1126     for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
1127     final long stamp = readLocker.apply(sl);
1128     assertValid(sl, stamp);
1129     assertNoLongerValidStampsThrow.run();
1130     assertThrows(IllegalMonitorStateException.class,
1131     () -> sl.unlockWrite(stamp),
1132     () -> sl.unlockRead(sl.tryOptimisticRead()),
1133     () -> sl.unlockRead(0L));
1134     readUnlocker.accept(sl, stamp);
1135     assertUnlocked(sl);
1136     assertNoLongerValidStampsThrow.run();
1137     }
1138 jsr166 1.26
1139 jsr166 1.27 for (Function<StampedLock, Long> writeLocker : writeLockers())
1140     for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
1141 jsr166 1.26 final long stamp = writeLocker.apply(sl);
1142 jsr166 1.27 assertValid(sl, stamp);
1143     assertNoLongerValidStampsThrow.run();
1144 jsr166 1.26 assertThrows(IllegalMonitorStateException.class,
1145 jsr166 1.27 () -> sl.unlockRead(stamp),
1146     () -> sl.unlockWrite(0L));
1147 jsr166 1.26 writeUnlocker.accept(sl, stamp);
1148 jsr166 1.27 assertUnlocked(sl);
1149     assertNoLongerValidStampsThrow.run();
1150 jsr166 1.26 }
1151     }
1152    
1153     /**
1154 jsr166 1.27 * Read locks can be very deeply nested
1155 jsr166 1.26 */
1156 jsr166 1.27 public void testDeeplyNestedReadLocks() {
1157     final StampedLock lock = new StampedLock();
1158     final int depth = 300;
1159     final long[] stamps = new long[depth];
1160     final List<Function<StampedLock, Long>> readLockers = readLockers();
1161     final List<BiConsumer<StampedLock, Long>> readUnlockers = readUnlockers();
1162     for (int i = 0; i < depth; i++) {
1163     Function<StampedLock, Long> readLocker
1164     = readLockers.get(i % readLockers.size());
1165     long stamp = readLocker.apply(lock);
1166     assertEquals(i + 1, lock.getReadLockCount());
1167     assertTrue(lock.isReadLocked());
1168     stamps[i] = stamp;
1169     }
1170     for (int i = 0; i < depth; i++) {
1171     BiConsumer<StampedLock, Long> readUnlocker
1172     = readUnlockers.get(i % readUnlockers.size());
1173     assertEquals(depth - i, lock.getReadLockCount());
1174     assertTrue(lock.isReadLocked());
1175     readUnlocker.accept(lock, stamps[depth - 1 - i]);
1176 jsr166 1.25 }
1177 jsr166 1.27 assertUnlocked(lock);
1178 jsr166 1.25 }
1179 jsr166 1.1 }