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 package jsr166;
9 
10 import static java.util.concurrent.TimeUnit.MILLISECONDS;
11 
12 import java.util.concurrent.CountDownLatch;
13 import java.util.concurrent.locks.Lock;
14 import java.util.concurrent.locks.StampedLock;
15 
16 import junit.framework.Test;
17 import junit.framework.TestSuite;
18 
19 public class StampedLockTest extends JSR166TestCase {
20     // android-note: Removed because the CTS runner does a bad job of
21     // retrying tests that have suite() declarations.
22     //
23     // public static void main(String[] args) {
24     //     main(suite(), args);
25     // }
26     // public static Test suite() {
27     //     return new TestSuite(StampedLockTest.class);
28     // }
29 
30     /**
31      * A runnable calling writeLockInterruptibly
32      */
33     class InterruptibleLockRunnable extends CheckedRunnable {
34         final StampedLock lock;
InterruptibleLockRunnable(StampedLock l)35         InterruptibleLockRunnable(StampedLock l) { lock = l; }
realRun()36         public void realRun() throws InterruptedException {
37             lock.writeLockInterruptibly();
38         }
39     }
40 
41     /**
42      * A runnable calling writeLockInterruptibly that expects to be
43      * interrupted
44      */
45     class InterruptedLockRunnable extends CheckedInterruptedRunnable {
46         final StampedLock lock;
InterruptedLockRunnable(StampedLock l)47         InterruptedLockRunnable(StampedLock l) { lock = l; }
realRun()48         public void realRun() throws InterruptedException {
49             lock.writeLockInterruptibly();
50         }
51     }
52 
53     /**
54      * Releases write lock, checking isWriteLocked before and after
55      */
releaseWriteLock(StampedLock lock, long s)56     void releaseWriteLock(StampedLock lock, long s) {
57         assertTrue(lock.isWriteLocked());
58         lock.unlockWrite(s);
59         assertFalse(lock.isWriteLocked());
60     }
61 
62     /**
63      * Constructed StampedLock is in unlocked state
64      */
testConstructor()65     public void testConstructor() {
66         StampedLock lock;
67         lock = new StampedLock();
68         assertFalse(lock.isWriteLocked());
69         assertFalse(lock.isReadLocked());
70         assertEquals(lock.getReadLockCount(), 0);
71     }
72 
73     /**
74      * write-locking and read-locking an unlocked lock succeed
75      */
testLock()76     public void testLock() {
77         StampedLock lock = new StampedLock();
78         assertFalse(lock.isWriteLocked());
79         assertFalse(lock.isReadLocked());
80         assertEquals(lock.getReadLockCount(), 0);
81         long s = lock.writeLock();
82         assertTrue(lock.isWriteLocked());
83         assertFalse(lock.isReadLocked());
84         assertEquals(lock.getReadLockCount(), 0);
85         lock.unlockWrite(s);
86         assertFalse(lock.isWriteLocked());
87         assertFalse(lock.isReadLocked());
88         assertEquals(lock.getReadLockCount(), 0);
89         long rs = lock.readLock();
90         assertFalse(lock.isWriteLocked());
91         assertTrue(lock.isReadLocked());
92         assertEquals(lock.getReadLockCount(), 1);
93         lock.unlockRead(rs);
94         assertFalse(lock.isWriteLocked());
95         assertFalse(lock.isReadLocked());
96         assertEquals(lock.getReadLockCount(), 0);
97     }
98 
99     /**
100      * unlock releases either a read or write lock
101      */
testUnlock()102     public void testUnlock() {
103         StampedLock lock = new StampedLock();
104         assertFalse(lock.isWriteLocked());
105         assertFalse(lock.isReadLocked());
106         assertEquals(lock.getReadLockCount(), 0);
107         long s = lock.writeLock();
108         assertTrue(lock.isWriteLocked());
109         assertFalse(lock.isReadLocked());
110         assertEquals(lock.getReadLockCount(), 0);
111         lock.unlock(s);
112         assertFalse(lock.isWriteLocked());
113         assertFalse(lock.isReadLocked());
114         assertEquals(lock.getReadLockCount(), 0);
115         long rs = lock.readLock();
116         assertFalse(lock.isWriteLocked());
117         assertTrue(lock.isReadLocked());
118         assertEquals(lock.getReadLockCount(), 1);
119         lock.unlock(rs);
120         assertFalse(lock.isWriteLocked());
121         assertFalse(lock.isReadLocked());
122         assertEquals(lock.getReadLockCount(), 0);
123     }
124 
125     /**
126      * tryUnlockRead/Write succeeds if locked in associated mode else
127      * returns false
128      */
testTryUnlock()129     public void testTryUnlock() {
130         StampedLock lock = new StampedLock();
131         assertFalse(lock.isWriteLocked());
132         assertFalse(lock.isReadLocked());
133         assertEquals(lock.getReadLockCount(), 0);
134         long s = lock.writeLock();
135         assertTrue(lock.isWriteLocked());
136         assertFalse(lock.isReadLocked());
137         assertEquals(lock.getReadLockCount(), 0);
138         assertFalse(lock.tryUnlockRead());
139         assertTrue(lock.tryUnlockWrite());
140         assertFalse(lock.tryUnlockWrite());
141         assertFalse(lock.tryUnlockRead());
142         assertFalse(lock.isWriteLocked());
143         assertFalse(lock.isReadLocked());
144         assertEquals(lock.getReadLockCount(), 0);
145         long rs = lock.readLock();
146         assertFalse(lock.isWriteLocked());
147         assertTrue(lock.isReadLocked());
148         assertEquals(lock.getReadLockCount(), 1);
149         assertFalse(lock.tryUnlockWrite());
150         assertTrue(lock.tryUnlockRead());
151         assertFalse(lock.tryUnlockRead());
152         assertFalse(lock.tryUnlockWrite());
153         assertFalse(lock.isWriteLocked());
154         assertFalse(lock.isReadLocked());
155         assertEquals(lock.getReadLockCount(), 0);
156     }
157 
158     /**
159      * write-unlocking an unlocked lock throws IllegalMonitorStateException
160      */
testWriteUnlock_IMSE()161     public void testWriteUnlock_IMSE() {
162         StampedLock lock = new StampedLock();
163         try {
164             lock.unlockWrite(0L);
165             shouldThrow();
166         } catch (IllegalMonitorStateException success) {}
167     }
168 
169     /**
170      * write-unlocking an unlocked lock throws IllegalMonitorStateException
171      */
testWriteUnlock_IMSE2()172     public void testWriteUnlock_IMSE2() {
173         StampedLock lock = new StampedLock();
174         long s = lock.writeLock();
175         lock.unlockWrite(s);
176         try {
177             lock.unlockWrite(s);
178             shouldThrow();
179         } catch (IllegalMonitorStateException success) {}
180     }
181 
182     /**
183      * write-unlocking after readlock throws IllegalMonitorStateException
184      */
testWriteUnlock_IMSE3()185     public void testWriteUnlock_IMSE3() {
186         StampedLock lock = new StampedLock();
187         long s = lock.readLock();
188         try {
189             lock.unlockWrite(s);
190             shouldThrow();
191         } catch (IllegalMonitorStateException success) {}
192     }
193 
194     /**
195      * read-unlocking an unlocked lock throws IllegalMonitorStateException
196      */
testReadUnlock_IMSE()197     public void testReadUnlock_IMSE() {
198         StampedLock lock = new StampedLock();
199         long s = lock.readLock();
200         lock.unlockRead(s);
201         try {
202             lock.unlockRead(s);
203             shouldThrow();
204         } catch (IllegalMonitorStateException success) {}
205     }
206 
207     /**
208      * read-unlocking an unlocked lock throws IllegalMonitorStateException
209      */
testReadUnlock_IMSE2()210     public void testReadUnlock_IMSE2() {
211         StampedLock lock = new StampedLock();
212         try {
213             lock.unlockRead(0L);
214             shouldThrow();
215         } catch (IllegalMonitorStateException success) {}
216     }
217 
218     /**
219      * read-unlocking after writeLock throws IllegalMonitorStateException
220      */
testReadUnlock_IMSE3()221     public void testReadUnlock_IMSE3() {
222         StampedLock lock = new StampedLock();
223         long s = lock.writeLock();
224         try {
225             lock.unlockRead(s);
226             shouldThrow();
227         } catch (IllegalMonitorStateException success) {}
228     }
229 
230     /**
231      * validate(0) fails
232      */
testValidate0()233     public void testValidate0() {
234         StampedLock lock = new StampedLock();
235         assertFalse(lock.validate(0L));
236     }
237 
238     /**
239      * A stamp obtained from a successful lock operation validates
240      */
testValidate()241     public void testValidate() throws InterruptedException {
242         StampedLock lock = new StampedLock();
243         long s = lock.writeLock();
244         assertTrue(lock.validate(s));
245         lock.unlockWrite(s);
246         s = lock.readLock();
247         assertTrue(lock.validate(s));
248         lock.unlockRead(s);
249         assertTrue((s = lock.tryWriteLock()) != 0L);
250         assertTrue(lock.validate(s));
251         lock.unlockWrite(s);
252         assertTrue((s = lock.tryReadLock()) != 0L);
253         assertTrue(lock.validate(s));
254         lock.unlockRead(s);
255         assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
256         assertTrue(lock.validate(s));
257         lock.unlockWrite(s);
258         assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
259         assertTrue(lock.validate(s));
260         lock.unlockRead(s);
261         assertTrue((s = lock.tryOptimisticRead()) != 0L);
262     }
263 
264     /**
265      * A stamp obtained from an unsuccessful lock operation does not validate
266      */
testValidate2()267     public void testValidate2() throws InterruptedException {
268         StampedLock lock = new StampedLock();
269         long s;
270         assertTrue((s = lock.writeLock()) != 0L);
271         assertTrue(lock.validate(s));
272         assertFalse(lock.validate(lock.tryWriteLock()));
273         assertFalse(lock.validate(lock.tryWriteLock(10L, MILLISECONDS)));
274         assertFalse(lock.validate(lock.tryReadLock()));
275         assertFalse(lock.validate(lock.tryReadLock(10L, MILLISECONDS)));
276         assertFalse(lock.validate(lock.tryOptimisticRead()));
277         lock.unlockWrite(s);
278     }
279 
280     /**
281      * writeLockInterruptibly is interruptible
282      */
testWriteLockInterruptibly_Interruptible()283     public void testWriteLockInterruptibly_Interruptible()
284             throws InterruptedException {
285         final CountDownLatch running = new CountDownLatch(1);
286         final StampedLock lock = new StampedLock();
287         long s = lock.writeLock();
288         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
289             public void realRun() throws InterruptedException {
290                 running.countDown();
291                 lock.writeLockInterruptibly();
292             }});
293 
294         running.await();
295         waitForThreadToEnterWaitState(t, 100);
296         t.interrupt();
297         awaitTermination(t);
298         releaseWriteLock(lock, s);
299     }
300 
301     /**
302      * timed tryWriteLock is interruptible
303      */
testWriteTryLock_Interruptible()304     public void testWriteTryLock_Interruptible() throws InterruptedException {
305         final CountDownLatch running = new CountDownLatch(1);
306         final StampedLock lock = new StampedLock();
307         long s = lock.writeLock();
308         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
309             public void realRun() throws InterruptedException {
310                 running.countDown();
311                 lock.tryWriteLock(2 * LONG_DELAY_MS, MILLISECONDS);
312             }});
313 
314         running.await();
315         waitForThreadToEnterWaitState(t, 100);
316         t.interrupt();
317         awaitTermination(t);
318         releaseWriteLock(lock, s);
319     }
320 
321     /**
322      * readLockInterruptibly is interruptible
323      */
testReadLockInterruptibly_Interruptible()324     public void testReadLockInterruptibly_Interruptible()
325             throws InterruptedException {
326         final CountDownLatch running = new CountDownLatch(1);
327         final StampedLock lock = new StampedLock();
328         long s = lock.writeLock();
329         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
330             public void realRun() throws InterruptedException {
331                 running.countDown();
332                 lock.readLockInterruptibly();
333             }});
334 
335         running.await();
336         waitForThreadToEnterWaitState(t, 100);
337         t.interrupt();
338         awaitTermination(t);
339         releaseWriteLock(lock, s);
340     }
341 
342     /**
343      * timed tryReadLock is interruptible
344      */
testReadTryLock_Interruptible()345     public void testReadTryLock_Interruptible() throws InterruptedException {
346         final CountDownLatch running = new CountDownLatch(1);
347         final StampedLock lock = new StampedLock();
348         long s = lock.writeLock();
349         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
350             public void realRun() throws InterruptedException {
351                 running.countDown();
352                 lock.tryReadLock(2 * LONG_DELAY_MS, MILLISECONDS);
353             }});
354 
355         running.await();
356         waitForThreadToEnterWaitState(t, 100);
357         t.interrupt();
358         awaitTermination(t);
359         releaseWriteLock(lock, s);
360     }
361 
362     /**
363      * tryWriteLock on an unlocked lock succeeds
364      */
testWriteTryLock()365     public void testWriteTryLock() {
366         final StampedLock lock = new StampedLock();
367         long s = lock.tryWriteLock();
368         assertTrue(s != 0L);
369         assertTrue(lock.isWriteLocked());
370         long s2 = lock.tryWriteLock();
371         assertEquals(s2, 0L);
372         releaseWriteLock(lock, s);
373     }
374 
375     /**
376      * tryWriteLock fails if locked
377      */
testWriteTryLockWhenLocked()378     public void testWriteTryLockWhenLocked() {
379         final StampedLock lock = new StampedLock();
380         long s = lock.writeLock();
381         Thread t = newStartedThread(new CheckedRunnable() {
382             public void realRun() {
383                 long ws = lock.tryWriteLock();
384                 assertTrue(ws == 0L);
385             }});
386 
387         awaitTermination(t);
388         releaseWriteLock(lock, s);
389     }
390 
391     /**
392      * tryReadLock fails if write-locked
393      */
testReadTryLockWhenLocked()394     public void testReadTryLockWhenLocked() {
395         final StampedLock lock = new StampedLock();
396         long s = lock.writeLock();
397         Thread t = newStartedThread(new CheckedRunnable() {
398             public void realRun() {
399                 long rs = lock.tryReadLock();
400                 assertEquals(rs, 0L);
401             }});
402 
403         awaitTermination(t);
404         releaseWriteLock(lock, s);
405     }
406 
407     /**
408      * Multiple threads can hold a read lock when not write-locked
409      */
testMultipleReadLocks()410     public void testMultipleReadLocks() {
411         final StampedLock lock = new StampedLock();
412         final long s = lock.readLock();
413         Thread t = newStartedThread(new CheckedRunnable() {
414             public void realRun() throws InterruptedException {
415                 long s2 = lock.tryReadLock();
416                 assertTrue(s2 != 0L);
417                 lock.unlockRead(s2);
418                 long s3 = lock.tryReadLock(LONG_DELAY_MS, MILLISECONDS);
419                 assertTrue(s3 != 0L);
420                 lock.unlockRead(s3);
421                 long s4 = lock.readLock();
422                 lock.unlockRead(s4);
423             }});
424 
425         awaitTermination(t);
426         lock.unlockRead(s);
427     }
428 
429     /**
430      * A writelock succeeds only after a reading thread unlocks
431      */
testWriteAfterReadLock()432     public void testWriteAfterReadLock() throws InterruptedException {
433         final CountDownLatch running = new CountDownLatch(1);
434         final StampedLock lock = new StampedLock();
435         long rs = lock.readLock();
436         Thread t = newStartedThread(new CheckedRunnable() {
437             public void realRun() {
438                 running.countDown();
439                 long s = lock.writeLock();
440                 lock.unlockWrite(s);
441             }});
442 
443         running.await();
444         waitForThreadToEnterWaitState(t, 100);
445         assertFalse(lock.isWriteLocked());
446         lock.unlockRead(rs);
447         awaitTermination(t);
448         assertFalse(lock.isWriteLocked());
449     }
450 
451     /**
452      * A writelock succeeds only after reading threads unlock
453      */
testWriteAfterMultipleReadLocks()454     public void testWriteAfterMultipleReadLocks() {
455         final StampedLock lock = new StampedLock();
456         long s = lock.readLock();
457         Thread t1 = newStartedThread(new CheckedRunnable() {
458             public void realRun() {
459                 long rs = lock.readLock();
460                 lock.unlockRead(rs);
461             }});
462 
463         awaitTermination(t1);
464 
465         Thread t2 = newStartedThread(new CheckedRunnable() {
466             public void realRun() {
467                 long ws = lock.writeLock();
468                 lock.unlockWrite(ws);
469             }});
470 
471         assertFalse(lock.isWriteLocked());
472         lock.unlockRead(s);
473         awaitTermination(t2);
474         assertFalse(lock.isWriteLocked());
475     }
476 
477     /**
478      * Readlocks succeed only after a writing thread unlocks
479      */
testReadAfterWriteLock()480     public void testReadAfterWriteLock() {
481         final StampedLock lock = new StampedLock();
482         final long s = lock.writeLock();
483         Thread t1 = newStartedThread(new CheckedRunnable() {
484             public void realRun() {
485                 long rs = lock.readLock();
486                 lock.unlockRead(rs);
487             }});
488         Thread t2 = newStartedThread(new CheckedRunnable() {
489             public void realRun() {
490                 long rs = lock.readLock();
491                 lock.unlockRead(rs);
492             }});
493 
494         releaseWriteLock(lock, s);
495         awaitTermination(t1);
496         awaitTermination(t2);
497     }
498 
499     /**
500      * tryReadLock succeeds if readlocked but not writelocked
501      */
testTryLockWhenReadLocked()502     public void testTryLockWhenReadLocked() {
503         final StampedLock lock = new StampedLock();
504         long s = lock.readLock();
505         Thread t = newStartedThread(new CheckedRunnable() {
506             public void realRun() {
507                 long rs = lock.tryReadLock();
508                 threadAssertTrue(rs != 0L);
509                 lock.unlockRead(rs);
510             }});
511 
512         awaitTermination(t);
513         lock.unlockRead(s);
514     }
515 
516     /**
517      * tryWriteLock fails when readlocked
518      */
testWriteTryLockWhenReadLocked()519     public void testWriteTryLockWhenReadLocked() {
520         final StampedLock lock = new StampedLock();
521         long s = lock.readLock();
522         Thread t = newStartedThread(new CheckedRunnable() {
523             public void realRun() {
524                 long ws = lock.tryWriteLock();
525                 threadAssertEquals(ws, 0L);
526             }});
527 
528         awaitTermination(t);
529         lock.unlockRead(s);
530     }
531 
532     /**
533      * timed tryWriteLock times out if locked
534      */
testWriteTryLock_Timeout()535     public void testWriteTryLock_Timeout() {
536         final StampedLock lock = new StampedLock();
537         long s = lock.writeLock();
538         Thread t = newStartedThread(new CheckedRunnable() {
539             public void realRun() throws InterruptedException {
540                 long startTime = System.nanoTime();
541                 long timeoutMillis = 10;
542                 long ws = lock.tryWriteLock(timeoutMillis, MILLISECONDS);
543                 assertEquals(ws, 0L);
544                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
545             }});
546 
547         awaitTermination(t);
548         releaseWriteLock(lock, s);
549     }
550 
551     /**
552      * timed tryReadLock times out if write-locked
553      */
testReadTryLock_Timeout()554     public void testReadTryLock_Timeout() {
555         final StampedLock lock = new StampedLock();
556         long s = lock.writeLock();
557         Thread t = newStartedThread(new CheckedRunnable() {
558             public void realRun() throws InterruptedException {
559                 long startTime = System.nanoTime();
560                 long timeoutMillis = 10;
561                 long rs = lock.tryReadLock(timeoutMillis, MILLISECONDS);
562                 assertEquals(rs, 0L);
563                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
564             }});
565 
566         awaitTermination(t);
567         assertTrue(lock.isWriteLocked());
568         lock.unlockWrite(s);
569     }
570 
571     /**
572      * writeLockInterruptibly succeeds if unlocked, else is interruptible
573      */
testWriteLockInterruptibly()574     public void testWriteLockInterruptibly() throws InterruptedException {
575         final CountDownLatch running = new CountDownLatch(1);
576         final StampedLock lock = new StampedLock();
577         long s = lock.writeLockInterruptibly();
578         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
579             public void realRun() throws InterruptedException {
580                 running.countDown();
581                 lock.writeLockInterruptibly();
582             }});
583 
584         running.await();
585         waitForThreadToEnterWaitState(t, 100);
586         t.interrupt();
587         assertTrue(lock.isWriteLocked());
588         awaitTermination(t);
589         releaseWriteLock(lock, s);
590     }
591 
592     /**
593      * readLockInterruptibly succeeds if lock free else is interruptible
594      */
testReadLockInterruptibly()595     public void testReadLockInterruptibly() throws InterruptedException {
596         final CountDownLatch running = new CountDownLatch(1);
597         final StampedLock lock = new StampedLock();
598         long s;
599         s = lock.readLockInterruptibly();
600         lock.unlockRead(s);
601         s = lock.writeLockInterruptibly();
602         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
603             public void realRun() throws InterruptedException {
604                 running.countDown();
605                 lock.readLockInterruptibly();
606             }});
607 
608         running.await();
609         waitForThreadToEnterWaitState(t, 100);
610         t.interrupt();
611         awaitTermination(t);
612         releaseWriteLock(lock, s);
613     }
614 
615     /**
616      * A serialized lock deserializes as unlocked
617      */
testSerialization()618     public void testSerialization() {
619         StampedLock lock = new StampedLock();
620         lock.writeLock();
621         StampedLock clone = serialClone(lock);
622         assertTrue(lock.isWriteLocked());
623         assertFalse(clone.isWriteLocked());
624         long s = clone.writeLock();
625         assertTrue(clone.isWriteLocked());
626         clone.unlockWrite(s);
627         assertFalse(clone.isWriteLocked());
628     }
629 
630     /**
631      * toString indicates current lock state
632      */
testToString()633     public void testToString() {
634         StampedLock lock = new StampedLock();
635         assertTrue(lock.toString().contains("Unlocked"));
636         long s = lock.writeLock();
637         assertTrue(lock.toString().contains("Write-locked"));
638         lock.unlockWrite(s);
639         s = lock.readLock();
640         assertTrue(lock.toString().contains("Read-locks"));
641     }
642 
643     /**
644      * tryOptimisticRead succeeds and validates if unlocked, fails if locked
645      */
testValidateOptimistic()646     public void testValidateOptimistic() throws InterruptedException {
647         StampedLock lock = new StampedLock();
648         long s, p;
649         assertTrue((p = lock.tryOptimisticRead()) != 0L);
650         assertTrue(lock.validate(p));
651         assertTrue((s = lock.writeLock()) != 0L);
652         assertFalse((p = lock.tryOptimisticRead()) != 0L);
653         assertTrue(lock.validate(s));
654         lock.unlockWrite(s);
655         assertTrue((p = lock.tryOptimisticRead()) != 0L);
656         assertTrue(lock.validate(p));
657         assertTrue((s = lock.readLock()) != 0L);
658         assertTrue(lock.validate(s));
659         assertTrue((p = lock.tryOptimisticRead()) != 0L);
660         assertTrue(lock.validate(p));
661         lock.unlockRead(s);
662         assertTrue((s = lock.tryWriteLock()) != 0L);
663         assertTrue(lock.validate(s));
664         assertFalse((p = lock.tryOptimisticRead()) != 0L);
665         lock.unlockWrite(s);
666         assertTrue((s = lock.tryReadLock()) != 0L);
667         assertTrue(lock.validate(s));
668         assertTrue((p = lock.tryOptimisticRead()) != 0L);
669         lock.unlockRead(s);
670         assertTrue(lock.validate(p));
671         assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
672         assertFalse((p = lock.tryOptimisticRead()) != 0L);
673         assertTrue(lock.validate(s));
674         lock.unlockWrite(s);
675         assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
676         assertTrue(lock.validate(s));
677         assertTrue((p = lock.tryOptimisticRead()) != 0L);
678         lock.unlockRead(s);
679         assertTrue((p = lock.tryOptimisticRead()) != 0L);
680     }
681 
682     /**
683      * tryOptimisticRead stamp does not validate if a write lock intervenes
684      */
testValidateOptimisticWriteLocked()685     public void testValidateOptimisticWriteLocked() {
686         StampedLock lock = new StampedLock();
687         long s, p;
688         assertTrue((p = lock.tryOptimisticRead()) != 0L);
689         assertTrue((s = lock.writeLock()) != 0L);
690         assertFalse(lock.validate(p));
691         assertFalse((p = lock.tryOptimisticRead()) != 0L);
692         assertTrue(lock.validate(s));
693         lock.unlockWrite(s);
694     }
695 
696     /**
697      * tryOptimisticRead stamp does not validate if a write lock
698      * intervenes in another thread
699      */
testValidateOptimisticWriteLocked2()700     public void testValidateOptimisticWriteLocked2()
701             throws InterruptedException {
702         final CountDownLatch running = new CountDownLatch(1);
703         final StampedLock lock = new StampedLock();
704         long s, p;
705         assertTrue((p = lock.tryOptimisticRead()) != 0L);
706         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
707             public void realRun() throws InterruptedException {
708                 lock.writeLockInterruptibly();
709                 running.countDown();
710                 lock.writeLockInterruptibly();
711             }});
712 
713         running.await();
714         assertFalse(lock.validate(p));
715         assertFalse((p = lock.tryOptimisticRead()) != 0L);
716         t.interrupt();
717         awaitTermination(t);
718     }
719 
720     /**
721      * tryConvertToOptimisticRead succeeds and validates if successfully locked,
722      */
testTryConvertToOptimisticRead()723     public void testTryConvertToOptimisticRead() throws InterruptedException {
724         StampedLock lock = new StampedLock();
725         long s, p;
726         s = 0L;
727         assertFalse((p = lock.tryConvertToOptimisticRead(s)) != 0L);
728         assertTrue((s = lock.tryOptimisticRead()) != 0L);
729         assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
730         assertTrue((s = lock.writeLock()) != 0L);
731         assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
732         assertTrue(lock.validate(p));
733         assertTrue((s = lock.readLock()) != 0L);
734         assertTrue(lock.validate(s));
735         assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
736         assertTrue(lock.validate(p));
737         assertTrue((s = lock.tryWriteLock()) != 0L);
738         assertTrue(lock.validate(s));
739         assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
740         assertTrue(lock.validate(p));
741         assertTrue((s = lock.tryReadLock()) != 0L);
742         assertTrue(lock.validate(s));
743         assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
744         assertTrue(lock.validate(p));
745         assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
746         assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
747         assertTrue(lock.validate(p));
748         assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
749         assertTrue(lock.validate(s));
750         assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
751         assertTrue(lock.validate(p));
752     }
753 
754     /**
755      * tryConvertToReadLock succeeds and validates if successfully locked
756      * or lock free;
757      */
testTryConvertToReadLock()758     public void testTryConvertToReadLock() throws InterruptedException {
759         StampedLock lock = new StampedLock();
760         long s, p;
761         s = 0L;
762         assertFalse((p = lock.tryConvertToReadLock(s)) != 0L);
763         assertTrue((s = lock.tryOptimisticRead()) != 0L);
764         assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
765         lock.unlockRead(p);
766         assertTrue((s = lock.writeLock()) != 0L);
767         assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
768         assertTrue(lock.validate(p));
769         lock.unlockRead(p);
770         assertTrue((s = lock.readLock()) != 0L);
771         assertTrue(lock.validate(s));
772         assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
773         assertTrue(lock.validate(p));
774         lock.unlockRead(p);
775         assertTrue((s = lock.tryWriteLock()) != 0L);
776         assertTrue(lock.validate(s));
777         assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
778         assertTrue(lock.validate(p));
779         lock.unlockRead(p);
780         assertTrue((s = lock.tryReadLock()) != 0L);
781         assertTrue(lock.validate(s));
782         assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
783         assertTrue(lock.validate(p));
784         lock.unlockRead(p);
785         assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
786         assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
787         assertTrue(lock.validate(p));
788         lock.unlockRead(p);
789         assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
790         assertTrue(lock.validate(s));
791         assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
792         assertTrue(lock.validate(p));
793         lock.unlockRead(p);
794     }
795 
796     /**
797      * tryConvertToWriteLock succeeds and validates if successfully locked
798      * or lock free;
799      */
testTryConvertToWriteLock()800     public void testTryConvertToWriteLock() throws InterruptedException {
801         StampedLock lock = new StampedLock();
802         long s, p;
803         s = 0L;
804         assertFalse((p = lock.tryConvertToWriteLock(s)) != 0L);
805         assertTrue((s = lock.tryOptimisticRead()) != 0L);
806         assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
807         lock.unlockWrite(p);
808         assertTrue((s = lock.writeLock()) != 0L);
809         assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
810         assertTrue(lock.validate(p));
811         lock.unlockWrite(p);
812         assertTrue((s = lock.readLock()) != 0L);
813         assertTrue(lock.validate(s));
814         assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
815         assertTrue(lock.validate(p));
816         lock.unlockWrite(p);
817         assertTrue((s = lock.tryWriteLock()) != 0L);
818         assertTrue(lock.validate(s));
819         assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
820         assertTrue(lock.validate(p));
821         lock.unlockWrite(p);
822         assertTrue((s = lock.tryReadLock()) != 0L);
823         assertTrue(lock.validate(s));
824         assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
825         assertTrue(lock.validate(p));
826         lock.unlockWrite(p);
827         assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
828         assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
829         assertTrue(lock.validate(p));
830         lock.unlockWrite(p);
831         assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
832         assertTrue(lock.validate(s));
833         assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
834         assertTrue(lock.validate(p));
835         lock.unlockWrite(p);
836     }
837 
838     /**
839      * asWriteLock can be locked and unlocked
840      */
testAsWriteLock()841     public void testAsWriteLock() {
842         StampedLock sl = new StampedLock();
843         Lock lock = sl.asWriteLock();
844         lock.lock();
845         assertFalse(lock.tryLock());
846         lock.unlock();
847         assertTrue(lock.tryLock());
848     }
849 
850     /**
851      * asReadLock can be locked and unlocked
852      */
testAsReadLock()853     public void testAsReadLock() {
854         StampedLock sl = new StampedLock();
855         Lock lock = sl.asReadLock();
856         lock.lock();
857         lock.unlock();
858         assertTrue(lock.tryLock());
859     }
860 
861     /**
862      * asReadWriteLock.writeLock can be locked and unlocked
863      */
testAsReadWriteLockWriteLock()864     public void testAsReadWriteLockWriteLock() {
865         StampedLock sl = new StampedLock();
866         Lock lock = sl.asReadWriteLock().writeLock();
867         lock.lock();
868         assertFalse(lock.tryLock());
869         lock.unlock();
870         assertTrue(lock.tryLock());
871     }
872 
873     /**
874      * asReadWriteLock.readLock can be locked and unlocked
875      */
testAsReadWriteLockReadLock()876     public void testAsReadWriteLockReadLock() {
877         StampedLock sl = new StampedLock();
878         Lock lock = sl.asReadWriteLock().readLock();
879         lock.lock();
880         lock.unlock();
881         assertTrue(lock.tryLock());
882     }
883 
884 }
885