ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/StampedLockTest.java
Revision: 1.38
Committed: Thu Sep 21 17:52:52 2017 UTC (6 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.37: +46 -0 lines
Log Message:
add new tests testNonReentrant, testNoOwnership

File Contents

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