ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/StampedLockTest.java
Revision: 1.20
Committed: Tue Jun 7 07:20:09 2016 UTC (7 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.19: +6 -0 lines
Log Message:
tryConvertToOptimisticRead should return input optimistic stamp when currently read-locked

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