ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/StampedLockTest.java
Revision: 1.33
Committed: Sat Feb 18 14:32:09 2017 UTC (7 years, 2 months ago) by jsr166
Branch: MAIN
Changes since 1.32: +25 -19 lines
Log Message:
various minor improvements

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.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 StampedLock lock = new StampedLock();
276 jsr166 1.12
277 jsr166 1.27 Action[] interruptibleLockActions = {
278     () -> lock.writeLockInterruptibly(),
279     () -> lock.tryWriteLock(Long.MIN_VALUE, DAYS),
280     () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
281     () -> lock.readLockInterruptibly(),
282     () -> lock.tryReadLock(Long.MIN_VALUE, DAYS),
283     () -> lock.tryReadLock(Long.MAX_VALUE, DAYS),
284     () -> lock.asWriteLock().lockInterruptibly(),
285     () -> lock.asWriteLock().tryLock(0L, DAYS),
286     () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
287     () -> lock.asReadLock().lockInterruptibly(),
288     () -> lock.asReadLock().tryLock(0L, DAYS),
289     () -> lock.asReadLock().tryLock(Long.MAX_VALUE, DAYS),
290     };
291     shuffle(interruptibleLockActions);
292    
293     assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
294     {
295     long s = lock.writeLock();
296     assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
297     lock.unlockWrite(s);
298     }
299     {
300     long s = lock.readLock();
301     assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
302     lock.unlockRead(s);
303     }
304     }
305    
306     void assertThrowInterruptedExceptionWhenInterrupted(Action[] actions) {
307     int n = actions.length;
308     Future<?>[] futures = new Future<?>[n];
309     CountDownLatch threadsStarted = new CountDownLatch(n);
310     CountDownLatch done = new CountDownLatch(n);
311    
312     for (int i = 0; i < n; i++) {
313     Action action = actions[i];
314     futures[i] = cachedThreadPool.submit(new CheckedRunnable() {
315     public void realRun() throws Throwable {
316     threadsStarted.countDown();
317     try {
318     action.run();
319     shouldThrow();
320     }
321     catch (InterruptedException success) {}
322     catch (Throwable fail) { threadUnexpectedException(fail); }
323     assertFalse(Thread.interrupted());
324     done.countDown();
325     }});
326     }
327    
328     await(threadsStarted);
329     assertEquals(n, done.getCount());
330     for (Future<?> future : futures) // Interrupt all the tasks
331     future.cancel(true);
332     await(done);
333 dl 1.4 }
334    
335     /**
336 jsr166 1.27 * interruptible operations throw InterruptedException when write locked and interrupted
337 dl 1.4 */
338 jsr166 1.27 public void testInterruptibleOperationsThrowInterruptedExceptionWriteLockedInterrupted() {
339 dl 1.4 final StampedLock lock = new StampedLock();
340     long s = lock.writeLock();
341 jsr166 1.12
342 jsr166 1.27 Action[] interruptibleLockBlockingActions = {
343     () -> lock.writeLockInterruptibly(),
344     () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
345     () -> lock.readLockInterruptibly(),
346     () -> lock.tryReadLock(Long.MAX_VALUE, DAYS),
347     () -> lock.asWriteLock().lockInterruptibly(),
348     () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
349     () -> lock.asReadLock().lockInterruptibly(),
350     () -> lock.asReadLock().tryLock(Long.MAX_VALUE, DAYS),
351     };
352     shuffle(interruptibleLockBlockingActions);
353    
354     assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions);
355 dl 1.4 }
356    
357     /**
358 jsr166 1.27 * interruptible operations throw InterruptedException when read locked and interrupted
359 dl 1.4 */
360 jsr166 1.27 public void testInterruptibleOperationsThrowInterruptedExceptionReadLockedInterrupted() {
361 dl 1.4 final StampedLock lock = new StampedLock();
362 jsr166 1.27 long s = lock.readLock();
363    
364     Action[] interruptibleLockBlockingActions = {
365     () -> lock.writeLockInterruptibly(),
366     () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
367     () -> lock.asWriteLock().lockInterruptibly(),
368     () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
369     };
370     shuffle(interruptibleLockBlockingActions);
371 jsr166 1.12
372 jsr166 1.27 assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions);
373 dl 1.4 }
374    
375     /**
376 jsr166 1.27 * Non-interruptible operations ignore and preserve interrupt status
377 dl 1.4 */
378 jsr166 1.27 public void testNonInterruptibleOperationsIgnoreInterrupts() {
379 dl 1.4 final StampedLock lock = new StampedLock();
380 jsr166 1.27 Thread.currentThread().interrupt();
381    
382     for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
383     long s = assertValid(lock, lock.readLock());
384     readUnlocker.accept(lock, s);
385     s = assertValid(lock, lock.tryReadLock());
386     readUnlocker.accept(lock, s);
387     }
388    
389     lock.asReadLock().lock();
390     lock.asReadLock().unlock();
391    
392     for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
393     long s = assertValid(lock, lock.writeLock());
394     writeUnlocker.accept(lock, s);
395     s = assertValid(lock, lock.tryWriteLock());
396     writeUnlocker.accept(lock, s);
397     }
398    
399     lock.asWriteLock().lock();
400     lock.asWriteLock().unlock();
401 jsr166 1.12
402 jsr166 1.27 assertTrue(Thread.interrupted());
403 dl 1.4 }
404    
405     /**
406     * tryWriteLock on an unlocked lock succeeds
407     */
408 jsr166 1.27 public void testTryWriteLock() {
409 dl 1.4 final StampedLock lock = new StampedLock();
410     long s = lock.tryWriteLock();
411     assertTrue(s != 0L);
412     assertTrue(lock.isWriteLocked());
413 jsr166 1.27 assertEquals(0L, lock.tryWriteLock());
414 dl 1.4 releaseWriteLock(lock, s);
415     }
416    
417     /**
418     * tryWriteLock fails if locked
419     */
420 jsr166 1.27 public void testTryWriteLockWhenLocked() {
421 dl 1.4 final StampedLock lock = new StampedLock();
422     long s = lock.writeLock();
423     Thread t = newStartedThread(new CheckedRunnable() {
424     public void realRun() {
425 jsr166 1.27 assertEquals(0L, lock.tryWriteLock());
426 dl 1.4 }});
427 jsr166 1.12
428 jsr166 1.27 assertEquals(0L, lock.tryWriteLock());
429 dl 1.4 awaitTermination(t);
430     releaseWriteLock(lock, s);
431     }
432    
433     /**
434     * tryReadLock fails if write-locked
435     */
436 jsr166 1.27 public void testTryReadLockWhenLocked() {
437 dl 1.4 final StampedLock lock = new StampedLock();
438     long s = lock.writeLock();
439     Thread t = newStartedThread(new CheckedRunnable() {
440     public void realRun() {
441 jsr166 1.27 assertEquals(0L, lock.tryReadLock());
442 dl 1.4 }});
443 jsr166 1.12
444 jsr166 1.27 assertEquals(0L, lock.tryReadLock());
445 dl 1.4 awaitTermination(t);
446     releaseWriteLock(lock, s);
447     }
448    
449     /**
450     * Multiple threads can hold a read lock when not write-locked
451     */
452     public void testMultipleReadLocks() {
453     final StampedLock lock = new StampedLock();
454     final long s = lock.readLock();
455     Thread t = newStartedThread(new CheckedRunnable() {
456     public void realRun() throws InterruptedException {
457     long s2 = lock.tryReadLock();
458 jsr166 1.27 assertValid(lock, s2);
459 dl 1.4 lock.unlockRead(s2);
460     long s3 = lock.tryReadLock(LONG_DELAY_MS, MILLISECONDS);
461 jsr166 1.27 assertValid(lock, s3);
462 dl 1.4 lock.unlockRead(s3);
463     long s4 = lock.readLock();
464 jsr166 1.27 assertValid(lock, s4);
465 dl 1.4 lock.unlockRead(s4);
466 jsr166 1.27 lock.asReadLock().lock();
467     lock.asReadLock().unlock();
468     lock.asReadLock().lockInterruptibly();
469     lock.asReadLock().unlock();
470     lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS);
471     lock.asReadLock().unlock();
472 dl 1.4 }});
473 jsr166 1.12
474 dl 1.4 awaitTermination(t);
475     lock.unlockRead(s);
476     }
477    
478     /**
479 jsr166 1.33 * writeLock() succeeds only after a reading thread unlocks
480 dl 1.4 */
481 jsr166 1.11 public void testWriteAfterReadLock() throws InterruptedException {
482 jsr166 1.33 final CountDownLatch aboutToLock = new CountDownLatch(1);
483 dl 1.4 final StampedLock lock = new StampedLock();
484     long rs = lock.readLock();
485     Thread t = newStartedThread(new CheckedRunnable() {
486     public void realRun() {
487 jsr166 1.33 aboutToLock.countDown();
488 dl 1.4 long s = lock.writeLock();
489 jsr166 1.33 assertTrue(lock.isWriteLocked());
490     assertFalse(lock.isReadLocked());
491 dl 1.4 lock.unlockWrite(s);
492     }});
493 jsr166 1.12
494 jsr166 1.33 aboutToLock.await();
495     waitForThreadToEnterWaitState(t);
496 jsr166 1.11 assertFalse(lock.isWriteLocked());
497 jsr166 1.33 assertTrue(lock.isReadLocked());
498 jsr166 1.11 lock.unlockRead(rs);
499     awaitTermination(t);
500 jsr166 1.33 assertUnlocked(lock);
501 dl 1.4 }
502    
503     /**
504 jsr166 1.33 * writeLock() succeeds only after reading threads unlock
505 dl 1.4 */
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 jsr166 1.33 assertUnlocked(lock);
528 dl 1.4 }
529    
530     /**
531 jsr166 1.33 * readLock() succeed only after a writing thread unlocks
532 dl 1.4 */
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 jsr166 1.33 final Runnable acquireReleaseReadLock = new CheckedRunnable() {
538 dl 1.4 public void realRun() {
539 jsr166 1.27 threadsStarted.countDown();
540 dl 1.4 long rs = lock.readLock();
541 jsr166 1.33 assertTrue(lock.isReadLocked());
542     assertFalse(lock.isWriteLocked());
543 dl 1.4 lock.unlockRead(rs);
544 jsr166 1.33 }};
545     Thread t1 = newStartedThread(acquireReleaseReadLock);
546     Thread t2 = newStartedThread(acquireReleaseReadLock);
547 dl 1.4
548 jsr166 1.27 await(threadsStarted);
549 jsr166 1.33 waitForThreadToEnterWaitState(t1);
550     waitForThreadToEnterWaitState(t2);
551     assertTrue(lock.isWriteLocked());
552     assertFalse(lock.isReadLocked());
553 dl 1.4 releaseWriteLock(lock, s);
554     awaitTermination(t1);
555     awaitTermination(t2);
556 jsr166 1.33 assertUnlocked(lock);
557 dl 1.4 }
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 jsr166 1.32 final CountDownLatch locked = new CountDownLatch(1);
743 dl 1.4 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 jsr166 1.32 locked.countDown();
750 jsr166 1.11 lock.writeLockInterruptibly();
751     }});
752 jsr166 1.12
753 jsr166 1.32 locked.await();
754 jsr166 1.11 assertFalse(lock.validate(p));
755 jsr166 1.27 assertEquals(0L, lock.tryOptimisticRead());
756 jsr166 1.33 waitForThreadToEnterWaitState(t);
757 jsr166 1.11 t.interrupt();
758     awaitTermination(t);
759 jsr166 1.33 assertTrue(lock.isWriteLocked());
760 dl 1.4 }
761    
762     /**
763 jsr166 1.27 * tryConvertToOptimisticRead succeeds and validates if successfully locked
764 dl 1.4 */
765 jsr166 1.11 public void testTryConvertToOptimisticRead() throws InterruptedException {
766     StampedLock lock = new StampedLock();
767 jsr166 1.27 long s, p, q;
768 jsr166 1.19 assertEquals(0L, lock.tryConvertToOptimisticRead(0L));
769    
770 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
771 jsr166 1.19 assertEquals(s, lock.tryConvertToOptimisticRead(s));
772     assertTrue(lock.validate(s));
773    
774 jsr166 1.27 for (Function<StampedLock, Long> writeLocker : writeLockers()) {
775     s = assertValid(lock, writeLocker.apply(lock));
776     p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
777     assertFalse(lock.validate(s));
778     assertTrue(lock.validate(p));
779     assertUnlocked(lock);
780     }
781 jsr166 1.20
782 jsr166 1.27 for (Function<StampedLock, Long> readLocker : readLockers()) {
783     s = assertValid(lock, readLocker.apply(lock));
784     q = assertValid(lock, lock.tryOptimisticRead());
785     assertEquals(q, lock.tryConvertToOptimisticRead(q));
786     assertTrue(lock.validate(q));
787     assertTrue(lock.isReadLocked());
788     p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
789     assertTrue(lock.validate(p));
790     assertTrue(lock.validate(s));
791     assertUnlocked(lock);
792     assertEquals(q, lock.tryConvertToOptimisticRead(q));
793     assertTrue(lock.validate(q));
794     }
795 dl 1.4 }
796    
797     /**
798 jsr166 1.27 * tryConvertToReadLock succeeds for valid stamps
799 dl 1.4 */
800 jsr166 1.11 public void testTryConvertToReadLock() throws InterruptedException {
801     StampedLock lock = new StampedLock();
802     long s, p;
803 jsr166 1.22
804 jsr166 1.27 assertEquals(0L, lock.tryConvertToReadLock(0L));
805 jsr166 1.22
806 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
807     p = assertValid(lock, lock.tryConvertToReadLock(s));
808 jsr166 1.22 assertTrue(lock.isReadLocked());
809     assertEquals(1, lock.getReadLockCount());
810 jsr166 1.27 assertTrue(lock.validate(s));
811 jsr166 1.11 lock.unlockRead(p);
812 jsr166 1.22
813 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
814 jsr166 1.24 lock.readLock();
815 jsr166 1.27 p = assertValid(lock, lock.tryConvertToReadLock(s));
816 jsr166 1.24 assertTrue(lock.isReadLocked());
817     assertEquals(2, lock.getReadLockCount());
818     lock.unlockRead(p);
819     lock.unlockRead(p);
820 jsr166 1.27 assertUnlocked(lock);
821 jsr166 1.24
822 jsr166 1.27 for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
823     for (Function<StampedLock, Long> writeLocker : writeLockers()) {
824     s = assertValid(lock, writeLocker.apply(lock));
825     p = assertValid(lock, lock.tryConvertToReadLock(s));
826     assertFalse(lock.validate(s));
827     assertTrue(lock.isReadLocked());
828     assertEquals(1, lock.getReadLockCount());
829     readUnlocker.accept(lock, p);
830     }
831    
832     for (Function<StampedLock, Long> readLocker : readLockers()) {
833     s = assertValid(lock, readLocker.apply(lock));
834     assertEquals(s, lock.tryConvertToReadLock(s));
835     assertTrue(lock.validate(s));
836     assertTrue(lock.isReadLocked());
837     assertEquals(1, lock.getReadLockCount());
838     readUnlocker.accept(lock, s);
839     }
840     }
841 dl 1.4 }
842    
843     /**
844 jsr166 1.27 * tryConvertToWriteLock succeeds if lock available; fails if multiply read locked
845 dl 1.4 */
846 jsr166 1.11 public void testTryConvertToWriteLock() throws InterruptedException {
847     StampedLock lock = new StampedLock();
848     long s, p;
849 jsr166 1.21
850 jsr166 1.27 assertEquals(0L, lock.tryConvertToWriteLock(0L));
851 jsr166 1.21
852 jsr166 1.11 assertTrue((s = lock.tryOptimisticRead()) != 0L);
853     assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
854 jsr166 1.23 assertTrue(lock.isWriteLocked());
855 jsr166 1.11 lock.unlockWrite(p);
856 jsr166 1.21
857 jsr166 1.27 for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
858     for (Function<StampedLock, Long> writeLocker : writeLockers()) {
859     s = assertValid(lock, writeLocker.apply(lock));
860     assertEquals(s, lock.tryConvertToWriteLock(s));
861     assertTrue(lock.validate(s));
862     assertTrue(lock.isWriteLocked());
863     writeUnlocker.accept(lock, s);
864     }
865    
866     for (Function<StampedLock, Long> readLocker : readLockers()) {
867     s = assertValid(lock, readLocker.apply(lock));
868     p = assertValid(lock, lock.tryConvertToWriteLock(s));
869     assertFalse(lock.validate(s));
870     assertTrue(lock.validate(p));
871     assertTrue(lock.isWriteLocked());
872     writeUnlocker.accept(lock, p);
873     }
874     }
875 jsr166 1.21
876 jsr166 1.27 // failure if multiply read locked
877     for (Function<StampedLock, Long> readLocker : readLockers()) {
878     s = assertValid(lock, readLocker.apply(lock));
879     p = assertValid(lock, readLocker.apply(lock));
880     assertEquals(0L, lock.tryConvertToWriteLock(s));
881     assertTrue(lock.validate(s));
882     assertTrue(lock.validate(p));
883     assertEquals(2, lock.getReadLockCount());
884     lock.unlock(p);
885     lock.unlock(s);
886     assertUnlocked(lock);
887     }
888 dl 1.4 }
889    
890     /**
891     * asWriteLock can be locked and unlocked
892     */
893 jsr166 1.27 public void testAsWriteLock() throws Throwable {
894 dl 1.4 StampedLock sl = new StampedLock();
895     Lock lock = sl.asWriteLock();
896 jsr166 1.27 for (Action locker : lockLockers(lock)) {
897     locker.run();
898     assertTrue(sl.isWriteLocked());
899     assertFalse(sl.isReadLocked());
900     assertFalse(lock.tryLock());
901     lock.unlock();
902     assertUnlocked(sl);
903     }
904 dl 1.4 }
905    
906     /**
907     * asReadLock can be locked and unlocked
908     */
909 jsr166 1.27 public void testAsReadLock() throws Throwable {
910 dl 1.4 StampedLock sl = new StampedLock();
911     Lock lock = sl.asReadLock();
912 jsr166 1.27 for (Action locker : lockLockers(lock)) {
913     locker.run();
914     assertTrue(sl.isReadLocked());
915     assertFalse(sl.isWriteLocked());
916     assertEquals(1, sl.getReadLockCount());
917     locker.run();
918     assertTrue(sl.isReadLocked());
919     assertEquals(2, sl.getReadLockCount());
920     lock.unlock();
921     lock.unlock();
922     assertUnlocked(sl);
923     }
924 dl 1.4 }
925    
926     /**
927     * asReadWriteLock.writeLock can be locked and unlocked
928     */
929 jsr166 1.27 public void testAsReadWriteLockWriteLock() throws Throwable {
930 dl 1.4 StampedLock sl = new StampedLock();
931     Lock lock = sl.asReadWriteLock().writeLock();
932 jsr166 1.27 for (Action locker : lockLockers(lock)) {
933     locker.run();
934     assertTrue(sl.isWriteLocked());
935     assertFalse(sl.isReadLocked());
936     assertFalse(lock.tryLock());
937     lock.unlock();
938     assertUnlocked(sl);
939     }
940 dl 1.4 }
941    
942     /**
943     * asReadWriteLock.readLock can be locked and unlocked
944     */
945 jsr166 1.27 public void testAsReadWriteLockReadLock() throws Throwable {
946 dl 1.4 StampedLock sl = new StampedLock();
947     Lock lock = sl.asReadWriteLock().readLock();
948 jsr166 1.27 for (Action locker : lockLockers(lock)) {
949     locker.run();
950     assertTrue(sl.isReadLocked());
951     assertFalse(sl.isWriteLocked());
952     assertEquals(1, sl.getReadLockCount());
953     locker.run();
954     assertTrue(sl.isReadLocked());
955     assertEquals(2, sl.getReadLockCount());
956     lock.unlock();
957     lock.unlock();
958     assertUnlocked(sl);
959     }
960 dl 1.4 }
961 jsr166 1.1
962 jsr166 1.15 /**
963     * Lock.newCondition throws UnsupportedOperationException
964     */
965     public void testLockViewsDoNotSupportConditions() {
966     StampedLock sl = new StampedLock();
967     assertThrows(UnsupportedOperationException.class,
968     () -> sl.asWriteLock().newCondition(),
969     () -> sl.asReadLock().newCondition(),
970     () -> sl.asReadWriteLock().writeLock().newCondition(),
971     () -> sl.asReadWriteLock().readLock().newCondition());
972     }
973    
974 jsr166 1.16 /**
975     * Passing optimistic read stamps to unlock operations result in
976     * IllegalMonitorStateException
977     */
978     public void testCannotUnlockOptimisticReadStamps() {
979     Runnable[] actions = {
980     () -> {
981     StampedLock sl = new StampedLock();
982 jsr166 1.27 long stamp = assertValid(sl, sl.tryOptimisticRead());
983 jsr166 1.16 sl.unlockRead(stamp);
984     },
985     () -> {
986     StampedLock sl = new StampedLock();
987     long stamp = sl.tryOptimisticRead();
988     sl.unlock(stamp);
989     },
990    
991     () -> {
992     StampedLock sl = new StampedLock();
993     long stamp = sl.tryOptimisticRead();
994     sl.writeLock();
995     sl.unlock(stamp);
996     },
997     () -> {
998     StampedLock sl = new StampedLock();
999     sl.readLock();
1000 jsr166 1.27 long stamp = assertValid(sl, sl.tryOptimisticRead());
1001 jsr166 1.16 sl.unlockRead(stamp);
1002     },
1003     () -> {
1004     StampedLock sl = new StampedLock();
1005     sl.readLock();
1006 jsr166 1.27 long stamp = assertValid(sl, sl.tryOptimisticRead());
1007 jsr166 1.16 sl.unlock(stamp);
1008     },
1009    
1010     () -> {
1011     StampedLock sl = new StampedLock();
1012     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1013 jsr166 1.27 assertValid(sl, stamp);
1014 jsr166 1.16 sl.writeLock();
1015     sl.unlockWrite(stamp);
1016     },
1017     () -> {
1018     StampedLock sl = new StampedLock();
1019     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1020     sl.writeLock();
1021     sl.unlock(stamp);
1022     },
1023     () -> {
1024     StampedLock sl = new StampedLock();
1025     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1026     sl.readLock();
1027     sl.unlockRead(stamp);
1028     },
1029     () -> {
1030     StampedLock sl = new StampedLock();
1031     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1032     sl.readLock();
1033     sl.unlock(stamp);
1034     },
1035    
1036     () -> {
1037     StampedLock sl = new StampedLock();
1038     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1039 jsr166 1.27 assertValid(sl, stamp);
1040 jsr166 1.16 sl.writeLock();
1041     sl.unlockWrite(stamp);
1042     },
1043     () -> {
1044     StampedLock sl = new StampedLock();
1045     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1046     sl.writeLock();
1047     sl.unlock(stamp);
1048     },
1049     () -> {
1050     StampedLock sl = new StampedLock();
1051     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1052     sl.readLock();
1053     sl.unlockRead(stamp);
1054     },
1055     () -> {
1056     StampedLock sl = new StampedLock();
1057 jsr166 1.18 sl.readLock();
1058     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1059 jsr166 1.27 assertValid(sl, stamp);
1060 jsr166 1.18 sl.readLock();
1061     sl.unlockRead(stamp);
1062     },
1063     () -> {
1064     StampedLock sl = new StampedLock();
1065     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1066     sl.readLock();
1067     sl.unlock(stamp);
1068     },
1069     () -> {
1070     StampedLock sl = new StampedLock();
1071     sl.readLock();
1072 jsr166 1.16 long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1073     sl.readLock();
1074     sl.unlock(stamp);
1075     },
1076     };
1077 jsr166 1.17
1078 jsr166 1.16 assertThrows(IllegalMonitorStateException.class, actions);
1079     }
1080    
1081 jsr166 1.25 static long writeLockInterruptiblyUninterrupted(StampedLock sl) {
1082     try { return sl.writeLockInterruptibly(); }
1083     catch (InterruptedException ex) { throw new AssertionError(ex); }
1084     }
1085    
1086     static long tryWriteLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1087     try { return sl.tryWriteLock(time, unit); }
1088     catch (InterruptedException ex) { throw new AssertionError(ex); }
1089     }
1090    
1091 jsr166 1.26 static long readLockInterruptiblyUninterrupted(StampedLock sl) {
1092     try { return sl.readLockInterruptibly(); }
1093     catch (InterruptedException ex) { throw new AssertionError(ex); }
1094     }
1095    
1096     static long tryReadLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1097     try { return sl.tryReadLock(time, unit); }
1098     catch (InterruptedException ex) { throw new AssertionError(ex); }
1099     }
1100    
1101 jsr166 1.25 /**
1102 jsr166 1.27 * Invalid stamps result in IllegalMonitorStateException
1103 jsr166 1.25 */
1104 jsr166 1.27 public void testInvalidStampsThrowIllegalMonitorStateException() {
1105     final StampedLock sl = new StampedLock();
1106    
1107     assertThrows(IllegalMonitorStateException.class,
1108     () -> sl.unlockWrite(0L),
1109     () -> sl.unlockRead(0L),
1110     () -> sl.unlock(0L));
1111    
1112     final long optimisticStamp = sl.tryOptimisticRead();
1113     final long readStamp = sl.readLock();
1114     sl.unlockRead(readStamp);
1115     final long writeStamp = sl.writeLock();
1116     sl.unlockWrite(writeStamp);
1117     assertTrue(optimisticStamp != 0L && readStamp != 0L && writeStamp != 0L);
1118     final long[] noLongerValidStamps = { optimisticStamp, readStamp, writeStamp };
1119     final Runnable assertNoLongerValidStampsThrow = () -> {
1120     for (long noLongerValidStamp : noLongerValidStamps)
1121     assertThrows(IllegalMonitorStateException.class,
1122     () -> sl.unlockWrite(noLongerValidStamp),
1123     () -> sl.unlockRead(noLongerValidStamp),
1124     () -> sl.unlock(noLongerValidStamp));
1125     };
1126     assertNoLongerValidStampsThrow.run();
1127 jsr166 1.25
1128 jsr166 1.27 for (Function<StampedLock, Long> readLocker : readLockers())
1129     for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
1130     final long stamp = readLocker.apply(sl);
1131     assertValid(sl, stamp);
1132     assertNoLongerValidStampsThrow.run();
1133     assertThrows(IllegalMonitorStateException.class,
1134     () -> sl.unlockWrite(stamp),
1135     () -> sl.unlockRead(sl.tryOptimisticRead()),
1136     () -> sl.unlockRead(0L));
1137     readUnlocker.accept(sl, stamp);
1138     assertUnlocked(sl);
1139     assertNoLongerValidStampsThrow.run();
1140     }
1141 jsr166 1.26
1142 jsr166 1.27 for (Function<StampedLock, Long> writeLocker : writeLockers())
1143     for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
1144 jsr166 1.26 final long stamp = writeLocker.apply(sl);
1145 jsr166 1.27 assertValid(sl, stamp);
1146     assertNoLongerValidStampsThrow.run();
1147 jsr166 1.26 assertThrows(IllegalMonitorStateException.class,
1148 jsr166 1.27 () -> sl.unlockRead(stamp),
1149     () -> sl.unlockWrite(0L));
1150 jsr166 1.26 writeUnlocker.accept(sl, stamp);
1151 jsr166 1.27 assertUnlocked(sl);
1152     assertNoLongerValidStampsThrow.run();
1153 jsr166 1.26 }
1154     }
1155    
1156     /**
1157 jsr166 1.27 * Read locks can be very deeply nested
1158 jsr166 1.26 */
1159 jsr166 1.27 public void testDeeplyNestedReadLocks() {
1160     final StampedLock lock = new StampedLock();
1161     final int depth = 300;
1162     final long[] stamps = new long[depth];
1163     final List<Function<StampedLock, Long>> readLockers = readLockers();
1164     final List<BiConsumer<StampedLock, Long>> readUnlockers = readUnlockers();
1165     for (int i = 0; i < depth; i++) {
1166     Function<StampedLock, Long> readLocker
1167     = readLockers.get(i % readLockers.size());
1168     long stamp = readLocker.apply(lock);
1169     assertEquals(i + 1, lock.getReadLockCount());
1170     assertTrue(lock.isReadLocked());
1171     stamps[i] = stamp;
1172     }
1173     for (int i = 0; i < depth; i++) {
1174     BiConsumer<StampedLock, Long> readUnlocker
1175     = readUnlockers.get(i % readUnlockers.size());
1176     assertEquals(depth - i, lock.getReadLockCount());
1177     assertTrue(lock.isReadLocked());
1178     readUnlocker.accept(lock, stamps[depth - 1 - i]);
1179 jsr166 1.25 }
1180 jsr166 1.27 assertUnlocked(lock);
1181 jsr166 1.25 }
1182 jsr166 1.1 }