ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/StampedLockTest.java
Revision: 1.24
Committed: Tue Jun 7 23:28:30 2016 UTC (7 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.23: +8 -0 lines
Log Message:
tryConvertToReadLock fails to convert an optimistic read stamp when already 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
770 assertFalse((p = lock.tryConvertToReadLock(0L)) != 0L);
771
772 assertTrue((s = lock.tryOptimisticRead()) != 0L);
773 assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
774 assertTrue(lock.isReadLocked());
775 assertEquals(1, lock.getReadLockCount());
776 lock.unlockRead(p);
777
778 assertTrue((s = lock.tryOptimisticRead()) != 0L);
779 lock.readLock();
780 assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
781 assertTrue(lock.isReadLocked());
782 assertEquals(2, lock.getReadLockCount());
783 lock.unlockRead(p);
784 lock.unlockRead(p);
785
786 assertTrue((s = lock.writeLock()) != 0L);
787 assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
788 assertTrue(lock.validate(p));
789 assertTrue(lock.isReadLocked());
790 assertEquals(1, lock.getReadLockCount());
791 lock.unlockRead(p);
792
793 assertTrue((s = lock.readLock()) != 0L);
794 assertTrue(lock.validate(s));
795 assertEquals(s, lock.tryConvertToReadLock(s));
796 assertTrue(lock.validate(s));
797 assertTrue(lock.isReadLocked());
798 assertEquals(1, lock.getReadLockCount());
799 lock.unlockRead(s);
800
801 assertTrue((s = lock.tryWriteLock()) != 0L);
802 assertTrue(lock.validate(s));
803 assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
804 assertTrue(lock.validate(p));
805 assertEquals(1, lock.getReadLockCount());
806 lock.unlockRead(p);
807
808 assertTrue((s = lock.tryReadLock()) != 0L);
809 assertTrue(lock.validate(s));
810 assertEquals(s, lock.tryConvertToReadLock(s));
811 assertTrue(lock.validate(s));
812 assertTrue(lock.isReadLocked());
813 assertEquals(1, lock.getReadLockCount());
814 lock.unlockRead(s);
815
816 assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
817 assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
818 assertTrue(lock.validate(p));
819 assertTrue(lock.isReadLocked());
820 assertEquals(1, lock.getReadLockCount());
821 lock.unlockRead(p);
822
823 assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
824 assertTrue(lock.validate(s));
825 assertEquals(s, lock.tryConvertToReadLock(s));
826 assertTrue(lock.validate(s));
827 assertTrue(lock.isReadLocked());
828 assertEquals(1, lock.getReadLockCount());
829 lock.unlockRead(s);
830 }
831
832 /**
833 * tryConvertToWriteLock succeeds and validates if successfully locked
834 * or lock free;
835 */
836 public void testTryConvertToWriteLock() throws InterruptedException {
837 StampedLock lock = new StampedLock();
838 long s, p;
839
840 assertFalse((p = lock.tryConvertToWriteLock(0L)) != 0L);
841
842 assertTrue((s = lock.tryOptimisticRead()) != 0L);
843 assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
844 assertTrue(lock.isWriteLocked());
845 lock.unlockWrite(p);
846
847 assertTrue((s = lock.writeLock()) != 0L);
848 assertEquals(s, lock.tryConvertToWriteLock(s));
849 assertTrue(lock.validate(s));
850 assertTrue(lock.isWriteLocked());
851 lock.unlockWrite(s);
852
853 assertTrue((s = lock.readLock()) != 0L);
854 assertTrue(lock.validate(s));
855 assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
856 assertTrue(lock.validate(p));
857 assertTrue(lock.isWriteLocked());
858 lock.unlockWrite(p);
859
860 assertTrue((s = lock.tryWriteLock()) != 0L);
861 assertTrue(lock.validate(s));
862 assertEquals(s, lock.tryConvertToWriteLock(s));
863 assertTrue(lock.validate(s));
864 assertTrue(lock.isWriteLocked());
865 lock.unlockWrite(s);
866
867 assertTrue((s = lock.tryReadLock()) != 0L);
868 assertTrue(lock.validate(s));
869 assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
870 assertTrue(lock.validate(p));
871 assertTrue(lock.isWriteLocked());
872 lock.unlockWrite(p);
873
874 assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
875 assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
876 assertTrue(lock.validate(p));
877 assertTrue(lock.isWriteLocked());
878 lock.unlockWrite(p);
879
880 assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
881 assertTrue(lock.validate(s));
882 assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
883 assertTrue(lock.validate(p));
884 assertTrue(lock.isWriteLocked());
885 lock.unlockWrite(p);
886 }
887
888 /**
889 * asWriteLock can be locked and unlocked
890 */
891 public void testAsWriteLock() {
892 StampedLock sl = new StampedLock();
893 Lock lock = sl.asWriteLock();
894 lock.lock();
895 assertFalse(lock.tryLock());
896 lock.unlock();
897 assertTrue(lock.tryLock());
898 }
899
900 /**
901 * asReadLock can be locked and unlocked
902 */
903 public void testAsReadLock() {
904 StampedLock sl = new StampedLock();
905 Lock lock = sl.asReadLock();
906 lock.lock();
907 lock.unlock();
908 assertTrue(lock.tryLock());
909 }
910
911 /**
912 * asReadWriteLock.writeLock can be locked and unlocked
913 */
914 public void testAsReadWriteLockWriteLock() {
915 StampedLock sl = new StampedLock();
916 Lock lock = sl.asReadWriteLock().writeLock();
917 lock.lock();
918 assertFalse(lock.tryLock());
919 lock.unlock();
920 assertTrue(lock.tryLock());
921 }
922
923 /**
924 * asReadWriteLock.readLock can be locked and unlocked
925 */
926 public void testAsReadWriteLockReadLock() {
927 StampedLock sl = new StampedLock();
928 Lock lock = sl.asReadWriteLock().readLock();
929 lock.lock();
930 lock.unlock();
931 assertTrue(lock.tryLock());
932 }
933
934 /**
935 * Lock.newCondition throws UnsupportedOperationException
936 */
937 public void testLockViewsDoNotSupportConditions() {
938 StampedLock sl = new StampedLock();
939 assertThrows(UnsupportedOperationException.class,
940 () -> sl.asWriteLock().newCondition(),
941 () -> sl.asReadLock().newCondition(),
942 () -> sl.asReadWriteLock().writeLock().newCondition(),
943 () -> sl.asReadWriteLock().readLock().newCondition());
944 }
945
946 /**
947 * Passing optimistic read stamps to unlock operations result in
948 * IllegalMonitorStateException
949 */
950 public void testCannotUnlockOptimisticReadStamps() {
951 Runnable[] actions = {
952 () -> {
953 StampedLock sl = new StampedLock();
954 long stamp = sl.tryOptimisticRead();
955 assertTrue(stamp != 0);
956 sl.unlockRead(stamp);
957 },
958 () -> {
959 StampedLock sl = new StampedLock();
960 long stamp = sl.tryOptimisticRead();
961 sl.unlock(stamp);
962 },
963
964 () -> {
965 StampedLock sl = new StampedLock();
966 long stamp = sl.tryOptimisticRead();
967 sl.writeLock();
968 sl.unlock(stamp);
969 },
970 () -> {
971 StampedLock sl = new StampedLock();
972 long stamp = sl.tryOptimisticRead();
973 sl.readLock();
974 sl.unlockRead(stamp);
975 },
976 () -> {
977 StampedLock sl = new StampedLock();
978 long stamp = sl.tryOptimisticRead();
979 sl.readLock();
980 sl.unlock(stamp);
981 },
982
983 () -> {
984 StampedLock sl = new StampedLock();
985 long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
986 assertTrue(stamp != 0);
987 sl.writeLock();
988 sl.unlockWrite(stamp);
989 },
990 () -> {
991 StampedLock sl = new StampedLock();
992 long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
993 sl.writeLock();
994 sl.unlock(stamp);
995 },
996 () -> {
997 StampedLock sl = new StampedLock();
998 long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
999 sl.readLock();
1000 sl.unlockRead(stamp);
1001 },
1002 () -> {
1003 StampedLock sl = new StampedLock();
1004 long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1005 sl.readLock();
1006 sl.unlock(stamp);
1007 },
1008
1009 () -> {
1010 StampedLock sl = new StampedLock();
1011 long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1012 assertTrue(stamp != 0);
1013 sl.writeLock();
1014 sl.unlockWrite(stamp);
1015 },
1016 () -> {
1017 StampedLock sl = new StampedLock();
1018 long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1019 sl.writeLock();
1020 sl.unlock(stamp);
1021 },
1022 () -> {
1023 StampedLock sl = new StampedLock();
1024 long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1025 sl.readLock();
1026 sl.unlockRead(stamp);
1027 },
1028 () -> {
1029 StampedLock sl = new StampedLock();
1030 sl.readLock();
1031 long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1032 assertTrue(stamp != 0);
1033 sl.readLock();
1034 sl.unlockRead(stamp);
1035 },
1036 () -> {
1037 StampedLock sl = new StampedLock();
1038 long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1039 sl.readLock();
1040 sl.unlock(stamp);
1041 },
1042 () -> {
1043 StampedLock sl = new StampedLock();
1044 sl.readLock();
1045 long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1046 sl.readLock();
1047 sl.unlock(stamp);
1048 },
1049 };
1050
1051 assertThrows(IllegalMonitorStateException.class, actions);
1052 }
1053
1054 }