ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/StampedLockTest.java
Revision: 1.25
Committed: Sun Jul 17 02:30:53 2016 UTC (7 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.24: +56 -0 lines
Log Message:
add testInvalidWriteStampsThrowIllegalMonitorStateException

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