ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/StampedLockTest.java
Revision: 1.32
Committed: Sat Feb 18 00:39:20 2017 UTC (7 years, 2 months ago) by jsr166
Branch: MAIN
Changes since 1.31: +3 -3 lines
Log Message:
testValidateOptimisticWriteLocked2: improve local variable name

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     * A writelock succeeds only after a reading thread unlocks
480     */
481 jsr166 1.11 public void testWriteAfterReadLock() throws InterruptedException {
482 jsr166 1.31 final CountDownLatch threadStarted = 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.31 threadStarted.countDown();
488 dl 1.4 long s = lock.writeLock();
489     lock.unlockWrite(s);
490     }});
491 jsr166 1.12
492 jsr166 1.31 threadStarted.await();
493 jsr166 1.27 waitForThreadToEnterWaitState(t, MEDIUM_DELAY_MS);
494 jsr166 1.11 assertFalse(lock.isWriteLocked());
495     lock.unlockRead(rs);
496     awaitTermination(t);
497     assertFalse(lock.isWriteLocked());
498 dl 1.4 }
499    
500     /**
501     * A writelock succeeds only after reading threads unlock
502     */
503     public void testWriteAfterMultipleReadLocks() {
504     final StampedLock lock = new StampedLock();
505     long s = lock.readLock();
506     Thread t1 = newStartedThread(new CheckedRunnable() {
507     public void realRun() {
508     long rs = lock.readLock();
509     lock.unlockRead(rs);
510     }});
511 jsr166 1.12
512 dl 1.4 awaitTermination(t1);
513    
514     Thread t2 = newStartedThread(new CheckedRunnable() {
515     public void realRun() {
516     long ws = lock.writeLock();
517     lock.unlockWrite(ws);
518     }});
519 jsr166 1.12
520 jsr166 1.27 assertTrue(lock.isReadLocked());
521 dl 1.4 assertFalse(lock.isWriteLocked());
522     lock.unlockRead(s);
523     awaitTermination(t2);
524     assertFalse(lock.isWriteLocked());
525     }
526    
527     /**
528     * Readlocks succeed only after a writing thread unlocks
529     */
530     public void testReadAfterWriteLock() {
531     final StampedLock lock = new StampedLock();
532 jsr166 1.27 final CountDownLatch threadsStarted = new CountDownLatch(2);
533 dl 1.4 final long s = lock.writeLock();
534     Thread t1 = newStartedThread(new CheckedRunnable() {
535     public void realRun() {
536 jsr166 1.27 threadsStarted.countDown();
537 dl 1.4 long rs = lock.readLock();
538     lock.unlockRead(rs);
539     }});
540     Thread t2 = newStartedThread(new CheckedRunnable() {
541     public void realRun() {
542 jsr166 1.27 threadsStarted.countDown();
543 dl 1.4 long rs = lock.readLock();
544     lock.unlockRead(rs);
545     }});
546    
547 jsr166 1.27 await(threadsStarted);
548     waitForThreadToEnterWaitState(t1, MEDIUM_DELAY_MS);
549     waitForThreadToEnterWaitState(t2, MEDIUM_DELAY_MS);
550 dl 1.4 releaseWriteLock(lock, s);
551     awaitTermination(t1);
552     awaitTermination(t2);
553     }
554    
555     /**
556 jsr166 1.27 * tryReadLock succeeds if read locked but not write locked
557 dl 1.4 */
558     public void testTryLockWhenReadLocked() {
559     final StampedLock lock = new StampedLock();
560     long s = lock.readLock();
561     Thread t = newStartedThread(new CheckedRunnable() {
562     public void realRun() {
563     long rs = lock.tryReadLock();
564 jsr166 1.27 assertValid(lock, rs);
565 dl 1.4 lock.unlockRead(rs);
566     }});
567    
568     awaitTermination(t);
569     lock.unlockRead(s);
570     }
571    
572     /**
573 jsr166 1.27 * tryWriteLock fails when read locked
574 dl 1.4 */
575 jsr166 1.27 public void testTryWriteLockWhenReadLocked() {
576 dl 1.4 final StampedLock lock = new StampedLock();
577     long s = lock.readLock();
578     Thread t = newStartedThread(new CheckedRunnable() {
579     public void realRun() {
580 jsr166 1.27 threadAssertEquals(0L, lock.tryWriteLock());
581 dl 1.4 }});
582    
583     awaitTermination(t);
584     lock.unlockRead(s);
585     }
586    
587     /**
588 jsr166 1.27 * timed lock operations time out if lock not available
589 dl 1.4 */
590 jsr166 1.27 public void testTimedLock_Timeout() throws Exception {
591     ArrayList<Future<?>> futures = new ArrayList<>();
592    
593     // Write locked
594 dl 1.4 final StampedLock lock = new StampedLock();
595 jsr166 1.27 long stamp = lock.writeLock();
596     assertEquals(0L, lock.tryReadLock(0L, DAYS));
597     assertEquals(0L, lock.tryReadLock(Long.MIN_VALUE, DAYS));
598     assertFalse(lock.asReadLock().tryLock(0L, DAYS));
599     assertFalse(lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS));
600     assertEquals(0L, lock.tryWriteLock(0L, DAYS));
601     assertEquals(0L, lock.tryWriteLock(Long.MIN_VALUE, DAYS));
602     assertFalse(lock.asWriteLock().tryLock(0L, DAYS));
603     assertFalse(lock.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
604    
605     futures.add(cachedThreadPool.submit(new CheckedRunnable() {
606 dl 1.4 public void realRun() throws InterruptedException {
607     long startTime = System.nanoTime();
608 jsr166 1.27 assertEquals(0L, lock.tryWriteLock(timeoutMillis(), MILLISECONDS));
609     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
610     }}));
611 dl 1.4
612 jsr166 1.27 futures.add(cachedThreadPool.submit(new CheckedRunnable() {
613     public void realRun() throws InterruptedException {
614     long startTime = System.nanoTime();
615     assertEquals(0L, lock.tryReadLock(timeoutMillis(), MILLISECONDS));
616     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
617     }}));
618    
619     // Read locked
620     final StampedLock lock2 = new StampedLock();
621     long stamp2 = lock2.readLock();
622     assertEquals(0L, lock2.tryWriteLock(0L, DAYS));
623     assertEquals(0L, lock2.tryWriteLock(Long.MIN_VALUE, DAYS));
624     assertFalse(lock2.asWriteLock().tryLock(0L, DAYS));
625     assertFalse(lock2.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
626 dl 1.4
627 jsr166 1.27 futures.add(cachedThreadPool.submit(new CheckedRunnable() {
628 dl 1.4 public void realRun() throws InterruptedException {
629     long startTime = System.nanoTime();
630 jsr166 1.27 assertEquals(0L, lock2.tryWriteLock(timeoutMillis(), MILLISECONDS));
631     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
632     }}));
633    
634     for (Future<?> future : futures)
635     assertNull(future.get());
636 jsr166 1.7
637 jsr166 1.27 releaseWriteLock(lock, stamp);
638     releaseReadLock(lock2, stamp2);
639 dl 1.4 }
640    
641     /**
642 jsr166 1.27 * writeLockInterruptibly succeeds if unlocked
643 dl 1.4 */
644 jsr166 1.11 public void testWriteLockInterruptibly() throws InterruptedException {
645 dl 1.4 final StampedLock lock = new StampedLock();
646 jsr166 1.11 long s = lock.writeLockInterruptibly();
647     assertTrue(lock.isWriteLocked());
648     releaseWriteLock(lock, s);
649 dl 1.4 }
650    
651     /**
652 jsr166 1.27 * readLockInterruptibly succeeds if lock free
653 dl 1.4 */
654 jsr166 1.11 public void testReadLockInterruptibly() throws InterruptedException {
655 dl 1.4 final StampedLock lock = new StampedLock();
656 jsr166 1.27
657     long s = assertValid(lock, lock.readLockInterruptibly());
658     assertTrue(lock.isReadLocked());
659 jsr166 1.11 lock.unlockRead(s);
660 jsr166 1.12
661 jsr166 1.27 lock.asReadLock().lockInterruptibly();
662     assertTrue(lock.isReadLocked());
663     lock.asReadLock().unlock();
664 dl 1.4 }
665    
666     /**
667     * A serialized lock deserializes as unlocked
668     */
669     public void testSerialization() {
670     StampedLock lock = new StampedLock();
671     lock.writeLock();
672     StampedLock clone = serialClone(lock);
673     assertTrue(lock.isWriteLocked());
674     assertFalse(clone.isWriteLocked());
675     long s = clone.writeLock();
676     assertTrue(clone.isWriteLocked());
677     clone.unlockWrite(s);
678     assertFalse(clone.isWriteLocked());
679     }
680 dl 1.5
681 dl 1.4 /**
682     * toString indicates current lock state
683     */
684     public void testToString() {
685     StampedLock lock = new StampedLock();
686     assertTrue(lock.toString().contains("Unlocked"));
687     long s = lock.writeLock();
688     assertTrue(lock.toString().contains("Write-locked"));
689     lock.unlockWrite(s);
690     s = lock.readLock();
691     assertTrue(lock.toString().contains("Read-locks"));
692     }
693    
694     /**
695 jsr166 1.27 * tryOptimisticRead succeeds and validates if unlocked, fails if
696     * exclusively locked
697 dl 1.4 */
698 jsr166 1.11 public void testValidateOptimistic() throws InterruptedException {
699     StampedLock lock = new StampedLock();
700 jsr166 1.27
701     assertValid(lock, lock.tryOptimisticRead());
702    
703     for (Function<StampedLock, Long> writeLocker : writeLockers()) {
704     long s = assertValid(lock, writeLocker.apply(lock));
705     assertEquals(0L, lock.tryOptimisticRead());
706     releaseWriteLock(lock, s);
707     }
708    
709     for (Function<StampedLock, Long> readLocker : readLockers()) {
710     long s = assertValid(lock, readLocker.apply(lock));
711     long p = assertValid(lock, lock.tryOptimisticRead());
712     releaseReadLock(lock, s);
713     assertTrue(lock.validate(p));
714     }
715    
716     assertValid(lock, lock.tryOptimisticRead());
717 dl 1.4 }
718    
719     /**
720     * tryOptimisticRead stamp does not validate if a write lock intervenes
721     */
722     public void testValidateOptimisticWriteLocked() {
723 jsr166 1.27 final StampedLock lock = new StampedLock();
724     final long p = assertValid(lock, lock.tryOptimisticRead());
725     final long s = assertValid(lock, lock.writeLock());
726 dl 1.4 assertFalse(lock.validate(p));
727 jsr166 1.27 assertEquals(0L, lock.tryOptimisticRead());
728 dl 1.4 assertTrue(lock.validate(s));
729     lock.unlockWrite(s);
730     }
731    
732     /**
733     * tryOptimisticRead stamp does not validate if a write lock
734     * intervenes in another thread
735     */
736 jsr166 1.11 public void testValidateOptimisticWriteLocked2()
737     throws InterruptedException {
738 jsr166 1.32 final CountDownLatch locked = new CountDownLatch(1);
739 dl 1.4 final StampedLock lock = new StampedLock();
740 jsr166 1.27 final long p = assertValid(lock, lock.tryOptimisticRead());
741    
742 dl 1.4 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
743 jsr166 1.11 public void realRun() throws InterruptedException {
744     lock.writeLockInterruptibly();
745 jsr166 1.32 locked.countDown();
746 jsr166 1.11 lock.writeLockInterruptibly();
747     }});
748 jsr166 1.12
749 jsr166 1.32 locked.await();
750 jsr166 1.11 assertFalse(lock.validate(p));
751 jsr166 1.27 assertEquals(0L, lock.tryOptimisticRead());
752 jsr166 1.11 t.interrupt();
753     awaitTermination(t);
754 dl 1.4 }
755    
756     /**
757 jsr166 1.27 * tryConvertToOptimisticRead succeeds and validates if successfully locked
758 dl 1.4 */
759 jsr166 1.11 public void testTryConvertToOptimisticRead() throws InterruptedException {
760     StampedLock lock = new StampedLock();
761 jsr166 1.27 long s, p, q;
762 jsr166 1.19 assertEquals(0L, lock.tryConvertToOptimisticRead(0L));
763    
764 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
765 jsr166 1.19 assertEquals(s, lock.tryConvertToOptimisticRead(s));
766     assertTrue(lock.validate(s));
767    
768 jsr166 1.27 for (Function<StampedLock, Long> writeLocker : writeLockers()) {
769     s = assertValid(lock, writeLocker.apply(lock));
770     p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
771     assertFalse(lock.validate(s));
772     assertTrue(lock.validate(p));
773     assertUnlocked(lock);
774     }
775 jsr166 1.20
776 jsr166 1.27 for (Function<StampedLock, Long> readLocker : readLockers()) {
777     s = assertValid(lock, readLocker.apply(lock));
778     q = assertValid(lock, lock.tryOptimisticRead());
779     assertEquals(q, lock.tryConvertToOptimisticRead(q));
780     assertTrue(lock.validate(q));
781     assertTrue(lock.isReadLocked());
782     p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
783     assertTrue(lock.validate(p));
784     assertTrue(lock.validate(s));
785     assertUnlocked(lock);
786     assertEquals(q, lock.tryConvertToOptimisticRead(q));
787     assertTrue(lock.validate(q));
788     }
789 dl 1.4 }
790    
791     /**
792 jsr166 1.27 * tryConvertToReadLock succeeds for valid stamps
793 dl 1.4 */
794 jsr166 1.11 public void testTryConvertToReadLock() throws InterruptedException {
795     StampedLock lock = new StampedLock();
796     long s, p;
797 jsr166 1.22
798 jsr166 1.27 assertEquals(0L, lock.tryConvertToReadLock(0L));
799 jsr166 1.22
800 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
801     p = assertValid(lock, lock.tryConvertToReadLock(s));
802 jsr166 1.22 assertTrue(lock.isReadLocked());
803     assertEquals(1, lock.getReadLockCount());
804 jsr166 1.27 assertTrue(lock.validate(s));
805 jsr166 1.11 lock.unlockRead(p);
806 jsr166 1.22
807 jsr166 1.27 s = assertValid(lock, lock.tryOptimisticRead());
808 jsr166 1.24 lock.readLock();
809 jsr166 1.27 p = assertValid(lock, lock.tryConvertToReadLock(s));
810 jsr166 1.24 assertTrue(lock.isReadLocked());
811     assertEquals(2, lock.getReadLockCount());
812     lock.unlockRead(p);
813     lock.unlockRead(p);
814 jsr166 1.27 assertUnlocked(lock);
815 jsr166 1.24
816 jsr166 1.27 for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
817     for (Function<StampedLock, Long> writeLocker : writeLockers()) {
818     s = assertValid(lock, writeLocker.apply(lock));
819     p = assertValid(lock, lock.tryConvertToReadLock(s));
820     assertFalse(lock.validate(s));
821     assertTrue(lock.isReadLocked());
822     assertEquals(1, lock.getReadLockCount());
823     readUnlocker.accept(lock, p);
824     }
825    
826     for (Function<StampedLock, Long> readLocker : readLockers()) {
827     s = assertValid(lock, readLocker.apply(lock));
828     assertEquals(s, lock.tryConvertToReadLock(s));
829     assertTrue(lock.validate(s));
830     assertTrue(lock.isReadLocked());
831     assertEquals(1, lock.getReadLockCount());
832     readUnlocker.accept(lock, s);
833     }
834     }
835 dl 1.4 }
836    
837     /**
838 jsr166 1.27 * tryConvertToWriteLock succeeds if lock available; fails if multiply read locked
839 dl 1.4 */
840 jsr166 1.11 public void testTryConvertToWriteLock() throws InterruptedException {
841     StampedLock lock = new StampedLock();
842     long s, p;
843 jsr166 1.21
844 jsr166 1.27 assertEquals(0L, lock.tryConvertToWriteLock(0L));
845 jsr166 1.21
846 jsr166 1.11 assertTrue((s = lock.tryOptimisticRead()) != 0L);
847     assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
848 jsr166 1.23 assertTrue(lock.isWriteLocked());
849 jsr166 1.11 lock.unlockWrite(p);
850 jsr166 1.21
851 jsr166 1.27 for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
852     for (Function<StampedLock, Long> writeLocker : writeLockers()) {
853     s = assertValid(lock, writeLocker.apply(lock));
854     assertEquals(s, lock.tryConvertToWriteLock(s));
855     assertTrue(lock.validate(s));
856     assertTrue(lock.isWriteLocked());
857     writeUnlocker.accept(lock, s);
858     }
859    
860     for (Function<StampedLock, Long> readLocker : readLockers()) {
861     s = assertValid(lock, readLocker.apply(lock));
862     p = assertValid(lock, lock.tryConvertToWriteLock(s));
863     assertFalse(lock.validate(s));
864     assertTrue(lock.validate(p));
865     assertTrue(lock.isWriteLocked());
866     writeUnlocker.accept(lock, p);
867     }
868     }
869 jsr166 1.21
870 jsr166 1.27 // failure if multiply read locked
871     for (Function<StampedLock, Long> readLocker : readLockers()) {
872     s = assertValid(lock, readLocker.apply(lock));
873     p = assertValid(lock, readLocker.apply(lock));
874     assertEquals(0L, lock.tryConvertToWriteLock(s));
875     assertTrue(lock.validate(s));
876     assertTrue(lock.validate(p));
877     assertEquals(2, lock.getReadLockCount());
878     lock.unlock(p);
879     lock.unlock(s);
880     assertUnlocked(lock);
881     }
882 dl 1.4 }
883    
884     /**
885     * asWriteLock can be locked and unlocked
886     */
887 jsr166 1.27 public void testAsWriteLock() throws Throwable {
888 dl 1.4 StampedLock sl = new StampedLock();
889     Lock lock = sl.asWriteLock();
890 jsr166 1.27 for (Action locker : lockLockers(lock)) {
891     locker.run();
892     assertTrue(sl.isWriteLocked());
893     assertFalse(sl.isReadLocked());
894     assertFalse(lock.tryLock());
895     lock.unlock();
896     assertUnlocked(sl);
897     }
898 dl 1.4 }
899    
900     /**
901     * asReadLock can be locked and unlocked
902     */
903 jsr166 1.27 public void testAsReadLock() throws Throwable {
904 dl 1.4 StampedLock sl = new StampedLock();
905     Lock lock = sl.asReadLock();
906 jsr166 1.27 for (Action locker : lockLockers(lock)) {
907     locker.run();
908     assertTrue(sl.isReadLocked());
909     assertFalse(sl.isWriteLocked());
910     assertEquals(1, sl.getReadLockCount());
911     locker.run();
912     assertTrue(sl.isReadLocked());
913     assertEquals(2, sl.getReadLockCount());
914     lock.unlock();
915     lock.unlock();
916     assertUnlocked(sl);
917     }
918 dl 1.4 }
919    
920     /**
921     * asReadWriteLock.writeLock can be locked and unlocked
922     */
923 jsr166 1.27 public void testAsReadWriteLockWriteLock() throws Throwable {
924 dl 1.4 StampedLock sl = new StampedLock();
925     Lock lock = sl.asReadWriteLock().writeLock();
926 jsr166 1.27 for (Action locker : lockLockers(lock)) {
927     locker.run();
928     assertTrue(sl.isWriteLocked());
929     assertFalse(sl.isReadLocked());
930     assertFalse(lock.tryLock());
931     lock.unlock();
932     assertUnlocked(sl);
933     }
934 dl 1.4 }
935    
936     /**
937     * asReadWriteLock.readLock can be locked and unlocked
938     */
939 jsr166 1.27 public void testAsReadWriteLockReadLock() throws Throwable {
940 dl 1.4 StampedLock sl = new StampedLock();
941     Lock lock = sl.asReadWriteLock().readLock();
942 jsr166 1.27 for (Action locker : lockLockers(lock)) {
943     locker.run();
944     assertTrue(sl.isReadLocked());
945     assertFalse(sl.isWriteLocked());
946     assertEquals(1, sl.getReadLockCount());
947     locker.run();
948     assertTrue(sl.isReadLocked());
949     assertEquals(2, sl.getReadLockCount());
950     lock.unlock();
951     lock.unlock();
952     assertUnlocked(sl);
953     }
954 dl 1.4 }
955 jsr166 1.1
956 jsr166 1.15 /**
957     * Lock.newCondition throws UnsupportedOperationException
958     */
959     public void testLockViewsDoNotSupportConditions() {
960     StampedLock sl = new StampedLock();
961     assertThrows(UnsupportedOperationException.class,
962     () -> sl.asWriteLock().newCondition(),
963     () -> sl.asReadLock().newCondition(),
964     () -> sl.asReadWriteLock().writeLock().newCondition(),
965     () -> sl.asReadWriteLock().readLock().newCondition());
966     }
967    
968 jsr166 1.16 /**
969     * Passing optimistic read stamps to unlock operations result in
970     * IllegalMonitorStateException
971     */
972     public void testCannotUnlockOptimisticReadStamps() {
973     Runnable[] actions = {
974     () -> {
975     StampedLock sl = new StampedLock();
976 jsr166 1.27 long stamp = assertValid(sl, sl.tryOptimisticRead());
977 jsr166 1.16 sl.unlockRead(stamp);
978     },
979     () -> {
980     StampedLock sl = new StampedLock();
981     long stamp = sl.tryOptimisticRead();
982     sl.unlock(stamp);
983     },
984    
985     () -> {
986     StampedLock sl = new StampedLock();
987     long stamp = sl.tryOptimisticRead();
988     sl.writeLock();
989     sl.unlock(stamp);
990     },
991     () -> {
992     StampedLock sl = new StampedLock();
993     sl.readLock();
994 jsr166 1.27 long stamp = assertValid(sl, sl.tryOptimisticRead());
995 jsr166 1.16 sl.unlockRead(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.unlock(stamp);
1002     },
1003    
1004     () -> {
1005     StampedLock sl = new StampedLock();
1006     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1007 jsr166 1.27 assertValid(sl, stamp);
1008 jsr166 1.16 sl.writeLock();
1009     sl.unlockWrite(stamp);
1010     },
1011     () -> {
1012     StampedLock sl = new StampedLock();
1013     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1014     sl.writeLock();
1015     sl.unlock(stamp);
1016     },
1017     () -> {
1018     StampedLock sl = new StampedLock();
1019     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1020     sl.readLock();
1021     sl.unlockRead(stamp);
1022     },
1023     () -> {
1024     StampedLock sl = new StampedLock();
1025     long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1026     sl.readLock();
1027     sl.unlock(stamp);
1028     },
1029    
1030     () -> {
1031     StampedLock sl = new StampedLock();
1032     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1033 jsr166 1.27 assertValid(sl, stamp);
1034 jsr166 1.16 sl.writeLock();
1035     sl.unlockWrite(stamp);
1036     },
1037     () -> {
1038     StampedLock sl = new StampedLock();
1039     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1040     sl.writeLock();
1041     sl.unlock(stamp);
1042     },
1043     () -> {
1044     StampedLock sl = new StampedLock();
1045     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1046     sl.readLock();
1047     sl.unlockRead(stamp);
1048     },
1049     () -> {
1050     StampedLock sl = new StampedLock();
1051 jsr166 1.18 sl.readLock();
1052     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1053 jsr166 1.27 assertValid(sl, stamp);
1054 jsr166 1.18 sl.readLock();
1055     sl.unlockRead(stamp);
1056     },
1057     () -> {
1058     StampedLock sl = new StampedLock();
1059     long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1060     sl.readLock();
1061     sl.unlock(stamp);
1062     },
1063     () -> {
1064     StampedLock sl = new StampedLock();
1065     sl.readLock();
1066 jsr166 1.16 long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1067     sl.readLock();
1068     sl.unlock(stamp);
1069     },
1070     };
1071 jsr166 1.17
1072 jsr166 1.16 assertThrows(IllegalMonitorStateException.class, actions);
1073     }
1074    
1075 jsr166 1.25 static long writeLockInterruptiblyUninterrupted(StampedLock sl) {
1076     try { return sl.writeLockInterruptibly(); }
1077     catch (InterruptedException ex) { throw new AssertionError(ex); }
1078     }
1079    
1080     static long tryWriteLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1081     try { return sl.tryWriteLock(time, unit); }
1082     catch (InterruptedException ex) { throw new AssertionError(ex); }
1083     }
1084    
1085 jsr166 1.26 static long readLockInterruptiblyUninterrupted(StampedLock sl) {
1086     try { return sl.readLockInterruptibly(); }
1087     catch (InterruptedException ex) { throw new AssertionError(ex); }
1088     }
1089    
1090     static long tryReadLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1091     try { return sl.tryReadLock(time, unit); }
1092     catch (InterruptedException ex) { throw new AssertionError(ex); }
1093     }
1094    
1095 jsr166 1.25 /**
1096 jsr166 1.27 * Invalid stamps result in IllegalMonitorStateException
1097 jsr166 1.25 */
1098 jsr166 1.27 public void testInvalidStampsThrowIllegalMonitorStateException() {
1099     final StampedLock sl = new StampedLock();
1100    
1101     assertThrows(IllegalMonitorStateException.class,
1102     () -> sl.unlockWrite(0L),
1103     () -> sl.unlockRead(0L),
1104     () -> sl.unlock(0L));
1105    
1106     final long optimisticStamp = sl.tryOptimisticRead();
1107     final long readStamp = sl.readLock();
1108     sl.unlockRead(readStamp);
1109     final long writeStamp = sl.writeLock();
1110     sl.unlockWrite(writeStamp);
1111     assertTrue(optimisticStamp != 0L && readStamp != 0L && writeStamp != 0L);
1112     final long[] noLongerValidStamps = { optimisticStamp, readStamp, writeStamp };
1113     final Runnable assertNoLongerValidStampsThrow = () -> {
1114     for (long noLongerValidStamp : noLongerValidStamps)
1115     assertThrows(IllegalMonitorStateException.class,
1116     () -> sl.unlockWrite(noLongerValidStamp),
1117     () -> sl.unlockRead(noLongerValidStamp),
1118     () -> sl.unlock(noLongerValidStamp));
1119     };
1120     assertNoLongerValidStampsThrow.run();
1121 jsr166 1.25
1122 jsr166 1.27 for (Function<StampedLock, Long> readLocker : readLockers())
1123     for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
1124     final long stamp = readLocker.apply(sl);
1125     assertValid(sl, stamp);
1126     assertNoLongerValidStampsThrow.run();
1127     assertThrows(IllegalMonitorStateException.class,
1128     () -> sl.unlockWrite(stamp),
1129     () -> sl.unlockRead(sl.tryOptimisticRead()),
1130     () -> sl.unlockRead(0L));
1131     readUnlocker.accept(sl, stamp);
1132     assertUnlocked(sl);
1133     assertNoLongerValidStampsThrow.run();
1134     }
1135 jsr166 1.26
1136 jsr166 1.27 for (Function<StampedLock, Long> writeLocker : writeLockers())
1137     for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
1138 jsr166 1.26 final long stamp = writeLocker.apply(sl);
1139 jsr166 1.27 assertValid(sl, stamp);
1140     assertNoLongerValidStampsThrow.run();
1141 jsr166 1.26 assertThrows(IllegalMonitorStateException.class,
1142 jsr166 1.27 () -> sl.unlockRead(stamp),
1143     () -> sl.unlockWrite(0L));
1144 jsr166 1.26 writeUnlocker.accept(sl, stamp);
1145 jsr166 1.27 assertUnlocked(sl);
1146     assertNoLongerValidStampsThrow.run();
1147 jsr166 1.26 }
1148     }
1149    
1150     /**
1151 jsr166 1.27 * Read locks can be very deeply nested
1152 jsr166 1.26 */
1153 jsr166 1.27 public void testDeeplyNestedReadLocks() {
1154     final StampedLock lock = new StampedLock();
1155     final int depth = 300;
1156     final long[] stamps = new long[depth];
1157     final List<Function<StampedLock, Long>> readLockers = readLockers();
1158     final List<BiConsumer<StampedLock, Long>> readUnlockers = readUnlockers();
1159     for (int i = 0; i < depth; i++) {
1160     Function<StampedLock, Long> readLocker
1161     = readLockers.get(i % readLockers.size());
1162     long stamp = readLocker.apply(lock);
1163     assertEquals(i + 1, lock.getReadLockCount());
1164     assertTrue(lock.isReadLocked());
1165     stamps[i] = stamp;
1166     }
1167     for (int i = 0; i < depth; i++) {
1168     BiConsumer<StampedLock, Long> readUnlocker
1169     = readUnlockers.get(i % readUnlockers.size());
1170     assertEquals(depth - i, lock.getReadLockCount());
1171     assertTrue(lock.isReadLocked());
1172     readUnlocker.accept(lock, stamps[depth - 1 - i]);
1173 jsr166 1.25 }
1174 jsr166 1.27 assertUnlocked(lock);
1175 jsr166 1.25 }
1176 jsr166 1.1 }