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

# Content
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 import static java.util.concurrent.TimeUnit.DAYS;
9 import static java.util.concurrent.TimeUnit.MILLISECONDS;
10
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.concurrent.CountDownLatch;
14 import java.util.concurrent.TimeUnit;
15 import java.util.concurrent.locks.Lock;
16 import java.util.concurrent.locks.StampedLock;
17 import java.util.function.BiConsumer;
18 import java.util.function.Consumer;
19 import java.util.function.Function;
20
21 import junit.framework.Test;
22 import junit.framework.TestSuite;
23
24 public class StampedLockTest extends JSR166TestCase {
25 public static void main(String[] args) {
26 main(suite(), args);
27 }
28 public static Test suite() {
29 return new TestSuite(StampedLockTest.class);
30 }
31
32 /**
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 long s = lock.writeLock();
177 lock.unlockWrite(s);
178 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 long s = lock.readLock();
190 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 long s = lock.readLock();
202 lock.unlockRead(s);
203 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 long s = lock.writeLock();
226 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 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 }
265
266 /**
267 * A stamp obtained from an unsuccessful lock operation does not validate
268 */
269 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 }
281
282 /**
283 * writeLockInterruptibly is interruptible
284 */
285 public void testWriteLockInterruptibly_Interruptible()
286 throws InterruptedException {
287 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
296 running.await();
297 waitForThreadToEnterWaitState(t, 100);
298 t.interrupt();
299 awaitTermination(t);
300 releaseWriteLock(lock, s);
301 }
302
303 /**
304 * timed tryWriteLock is interruptible
305 */
306 public void testWriteTryLock_Interruptible() throws InterruptedException {
307 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
316 running.await();
317 waitForThreadToEnterWaitState(t, 100);
318 t.interrupt();
319 awaitTermination(t);
320 releaseWriteLock(lock, s);
321 }
322
323 /**
324 * readLockInterruptibly is interruptible
325 */
326 public void testReadLockInterruptibly_Interruptible()
327 throws InterruptedException {
328 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
337 running.await();
338 waitForThreadToEnterWaitState(t, 100);
339 t.interrupt();
340 awaitTermination(t);
341 releaseWriteLock(lock, s);
342 }
343
344 /**
345 * timed tryReadLock is interruptible
346 */
347 public void testReadTryLock_Interruptible() throws InterruptedException {
348 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
357 running.await();
358 waitForThreadToEnterWaitState(t, 100);
359 t.interrupt();
360 awaitTermination(t);
361 releaseWriteLock(lock, s);
362 }
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
389 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
405 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
427 awaitTermination(t);
428 lock.unlockRead(s);
429 }
430
431 /**
432 * A writelock succeeds only after a reading thread unlocks
433 */
434 public void testWriteAfterReadLock() throws InterruptedException {
435 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
445 running.await();
446 waitForThreadToEnterWaitState(t, 100);
447 assertFalse(lock.isWriteLocked());
448 lock.unlockRead(rs);
449 awaitTermination(t);
450 assertFalse(lock.isWriteLocked());
451 }
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
465 awaitTermination(t1);
466
467 Thread t2 = newStartedThread(new CheckedRunnable() {
468 public void realRun() {
469 long ws = lock.writeLock();
470 lock.unlockWrite(ws);
471 }});
472
473 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
568 awaitTermination(t);
569 assertTrue(lock.isWriteLocked());
570 lock.unlockWrite(s);
571 }
572
573 /**
574 * writeLockInterruptibly succeeds if unlocked, else is interruptible
575 */
576 public void testWriteLockInterruptibly() throws InterruptedException {
577 final CountDownLatch running = new CountDownLatch(1);
578 final StampedLock lock = new StampedLock();
579 long s = lock.writeLockInterruptibly();
580 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
581 public void realRun() throws InterruptedException {
582 running.countDown();
583 lock.writeLockInterruptibly();
584 }});
585
586 running.await();
587 waitForThreadToEnterWaitState(t, 100);
588 t.interrupt();
589 assertTrue(lock.isWriteLocked());
590 awaitTermination(t);
591 releaseWriteLock(lock, s);
592 }
593
594 /**
595 * readLockInterruptibly succeeds if lock free else is interruptible
596 */
597 public void testReadLockInterruptibly() throws InterruptedException {
598 final CountDownLatch running = new CountDownLatch(1);
599 final StampedLock lock = new StampedLock();
600 long s;
601 s = lock.readLockInterruptibly();
602 lock.unlockRead(s);
603 s = lock.writeLockInterruptibly();
604 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
605 public void realRun() throws InterruptedException {
606 running.countDown();
607 lock.readLockInterruptibly();
608 }});
609
610 running.await();
611 waitForThreadToEnterWaitState(t, 100);
612 t.interrupt();
613 awaitTermination(t);
614 releaseWriteLock(lock, s);
615 }
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
632 /**
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 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 }
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 public void testValidateOptimisticWriteLocked2()
703 throws InterruptedException {
704 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 public void realRun() throws InterruptedException {
710 lock.writeLockInterruptibly();
711 running.countDown();
712 lock.writeLockInterruptibly();
713 }});
714
715 running.await();
716 assertFalse(lock.validate(p));
717 assertFalse((p = lock.tryOptimisticRead()) != 0L);
718 t.interrupt();
719 awaitTermination(t);
720 }
721
722 /**
723 * tryConvertToOptimisticRead succeeds and validates if successfully locked,
724 */
725 public void testTryConvertToOptimisticRead() throws InterruptedException {
726 StampedLock lock = new StampedLock();
727 long s, p;
728 assertEquals(0L, lock.tryConvertToOptimisticRead(0L));
729
730 assertTrue((s = lock.tryOptimisticRead()) != 0L);
731 assertEquals(s, lock.tryConvertToOptimisticRead(s));
732 assertTrue(lock.validate(s));
733
734 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 assertTrue((s = lock.writeLock()) != 0L);
741 assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
742 assertTrue(lock.validate(p));
743
744 assertTrue((s = lock.readLock()) != 0L);
745 assertTrue(lock.validate(s));
746 assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
747 assertTrue(lock.validate(p));
748
749 assertTrue((s = lock.tryWriteLock()) != 0L);
750 assertTrue(lock.validate(s));
751 assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
752 assertTrue(lock.validate(p));
753
754 assertTrue((s = lock.tryReadLock()) != 0L);
755 assertTrue(lock.validate(s));
756 assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
757 assertTrue(lock.validate(p));
758
759 assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
760 assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
761 assertTrue(lock.validate(p));
762
763 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 }
768
769 /**
770 * tryConvertToReadLock succeeds and validates if successfully locked
771 * or lock free;
772 */
773 public void testTryConvertToReadLock() throws InterruptedException {
774 StampedLock lock = new StampedLock();
775 long s, p;
776
777 assertFalse((p = lock.tryConvertToReadLock(0L)) != 0L);
778
779 assertTrue((s = lock.tryOptimisticRead()) != 0L);
780 assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
781 assertTrue(lock.isReadLocked());
782 assertEquals(1, lock.getReadLockCount());
783 lock.unlockRead(p);
784
785 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 assertTrue((s = lock.writeLock()) != 0L);
794 assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
795 assertTrue(lock.validate(p));
796 assertTrue(lock.isReadLocked());
797 assertEquals(1, lock.getReadLockCount());
798 lock.unlockRead(p);
799
800 assertTrue((s = lock.readLock()) != 0L);
801 assertTrue(lock.validate(s));
802 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 assertTrue((s = lock.tryWriteLock()) != 0L);
809 assertTrue(lock.validate(s));
810 assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
811 assertTrue(lock.validate(p));
812 assertEquals(1, lock.getReadLockCount());
813 lock.unlockRead(p);
814
815 assertTrue((s = lock.tryReadLock()) != 0L);
816 assertTrue(lock.validate(s));
817 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 assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
824 assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
825 assertTrue(lock.validate(p));
826 assertTrue(lock.isReadLocked());
827 assertEquals(1, lock.getReadLockCount());
828 lock.unlockRead(p);
829
830 assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
831 assertTrue(lock.validate(s));
832 assertEquals(s, lock.tryConvertToReadLock(s));
833 assertTrue(lock.validate(s));
834 assertTrue(lock.isReadLocked());
835 assertEquals(1, lock.getReadLockCount());
836 lock.unlockRead(s);
837 }
838
839 /**
840 * tryConvertToWriteLock succeeds and validates if successfully locked
841 * or lock free;
842 */
843 public void testTryConvertToWriteLock() throws InterruptedException {
844 StampedLock lock = new StampedLock();
845 long s, p;
846
847 assertFalse((p = lock.tryConvertToWriteLock(0L)) != 0L);
848
849 assertTrue((s = lock.tryOptimisticRead()) != 0L);
850 assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
851 assertTrue(lock.isWriteLocked());
852 lock.unlockWrite(p);
853
854 assertTrue((s = lock.writeLock()) != 0L);
855 assertEquals(s, lock.tryConvertToWriteLock(s));
856 assertTrue(lock.validate(s));
857 assertTrue(lock.isWriteLocked());
858 lock.unlockWrite(s);
859
860 assertTrue((s = lock.readLock()) != 0L);
861 assertTrue(lock.validate(s));
862 assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
863 assertTrue(lock.validate(p));
864 assertTrue(lock.isWriteLocked());
865 lock.unlockWrite(p);
866
867 assertTrue((s = lock.tryWriteLock()) != 0L);
868 assertTrue(lock.validate(s));
869 assertEquals(s, lock.tryConvertToWriteLock(s));
870 assertTrue(lock.validate(s));
871 assertTrue(lock.isWriteLocked());
872 lock.unlockWrite(s);
873
874 assertTrue((s = lock.tryReadLock()) != 0L);
875 assertTrue(lock.validate(s));
876 assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
877 assertTrue(lock.validate(p));
878 assertTrue(lock.isWriteLocked());
879 lock.unlockWrite(p);
880
881 assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
882 assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
883 assertTrue(lock.validate(p));
884 assertTrue(lock.isWriteLocked());
885 lock.unlockWrite(p);
886
887 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 assertTrue(lock.isWriteLocked());
892 lock.unlockWrite(p);
893 }
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
941 /**
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 /**
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 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 long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1053 sl.readLock();
1054 sl.unlock(stamp);
1055 },
1056 };
1057
1058 assertThrows(IllegalMonitorStateException.class, actions);
1059 }
1060
1061 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 }