ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/StampedLockTest.java
(Generate patch)

Comparing jsr166/src/test/tck/StampedLockTest.java (file contents):
Revision 1.2 by jsr166, Fri Feb 1 21:44:41 2013 UTC vs.
Revision 1.36 by jsr166, Mon May 29 19:15:03 2017 UTC

# Line 3 | Line 3
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 * Other contributors include Andrew Wright, Jeffrey Hayes,
7 * Pat Fisher, Mike Judd.
6   */
7  
8 < import junit.framework.*;
9 < import java.util.concurrent.atomic.AtomicBoolean;
10 < import java.util.concurrent.locks.Condition;
8 > import static java.util.concurrent.TimeUnit.DAYS;
9 > import static java.util.concurrent.TimeUnit.MILLISECONDS;
10 > import static java.util.concurrent.TimeUnit.SECONDS;
11 >
12 > import java.util.ArrayList;
13 > import java.util.List;
14 > import java.util.concurrent.CountDownLatch;
15 > import java.util.concurrent.Future;
16 > import java.util.concurrent.TimeUnit;
17   import java.util.concurrent.locks.Lock;
14 import java.util.concurrent.locks.ReadWriteLock;
18   import java.util.concurrent.locks.StampedLock;
19 < import java.util.concurrent.CountDownLatch;
20 < import static java.util.concurrent.TimeUnit.MILLISECONDS;
21 < import java.util.*;
19 > import java.util.function.BiConsumer;
20 > import java.util.function.Function;
21 >
22 > import junit.framework.Test;
23 > import junit.framework.TestSuite;
24  
25   public class StampedLockTest extends JSR166TestCase {
26      public static void main(String[] args) {
27 <        junit.textui.TestRunner.run(suite());
27 >        main(suite(), args);
28      }
29      public static Test suite() {
30          return new TestSuite(StampedLockTest.class);
31      }
32  
33 <    // XXXX Just a skeleton implementation for now.
34 <    public void testTODO() { fail("StampedLockTest needs help"); }
33 >    /**
34 >     * Releases write lock, checking isWriteLocked before and after
35 >     */
36 >    void releaseWriteLock(StampedLock lock, long stamp) {
37 >        assertTrue(lock.isWriteLocked());
38 >        assertValid(lock, stamp);
39 >        lock.unlockWrite(stamp);
40 >        assertFalse(lock.isWriteLocked());
41 >        assertFalse(lock.validate(stamp));
42 >    }
43 >
44 >    /**
45 >     * Releases read lock, checking isReadLocked before and after
46 >     */
47 >    void releaseReadLock(StampedLock lock, long stamp) {
48 >        assertTrue(lock.isReadLocked());
49 >        assertValid(lock, stamp);
50 >        lock.unlockRead(stamp);
51 >        assertFalse(lock.isReadLocked());
52 >        assertTrue(lock.validate(stamp));
53 >    }
54 >
55 >    long assertNonZero(long v) {
56 >        assertTrue(v != 0L);
57 >        return v;
58 >    }
59 >
60 >    long assertValid(StampedLock lock, long stamp) {
61 >        assertTrue(stamp != 0L);
62 >        assertTrue(lock.validate(stamp));
63 >        return stamp;
64 >    }
65 >
66 >    void assertUnlocked(StampedLock lock) {
67 >        assertFalse(lock.isReadLocked());
68 >        assertFalse(lock.isWriteLocked());
69 >        assertEquals(0, lock.getReadLockCount());
70 >        assertValid(lock, lock.tryOptimisticRead());
71 >    }
72 >
73 >    List<Action> lockLockers(Lock lock) {
74 >        List<Action> lockers = new ArrayList<>();
75 >        lockers.add(() -> lock.lock());
76 >        lockers.add(() -> lock.lockInterruptibly());
77 >        lockers.add(() -> lock.tryLock());
78 >        lockers.add(() -> lock.tryLock(Long.MIN_VALUE, DAYS));
79 >        lockers.add(() -> lock.tryLock(0L, DAYS));
80 >        lockers.add(() -> lock.tryLock(Long.MAX_VALUE, DAYS));
81 >        return lockers;
82 >    }
83 >
84 >    List<Function<StampedLock, Long>> readLockers() {
85 >        List<Function<StampedLock, Long>> readLockers = new ArrayList<>();
86 >        readLockers.add(sl -> sl.readLock());
87 >        readLockers.add(sl -> sl.tryReadLock());
88 >        readLockers.add(sl -> readLockInterruptiblyUninterrupted(sl));
89 >        readLockers.add(sl -> tryReadLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
90 >        readLockers.add(sl -> tryReadLockUninterrupted(sl, 0L, DAYS));
91 >        readLockers.add(sl -> sl.tryConvertToReadLock(sl.tryOptimisticRead()));
92 >        return readLockers;
93 >    }
94 >
95 >    List<BiConsumer<StampedLock, Long>> readUnlockers() {
96 >        List<BiConsumer<StampedLock, Long>> readUnlockers = new ArrayList<>();
97 >        readUnlockers.add((sl, stamp) -> sl.unlockRead(stamp));
98 >        readUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockRead()));
99 >        readUnlockers.add((sl, stamp) -> sl.asReadLock().unlock());
100 >        readUnlockers.add((sl, stamp) -> sl.unlock(stamp));
101 >        readUnlockers.add((sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
102 >        return readUnlockers;
103 >    }
104 >
105 >    List<Function<StampedLock, Long>> writeLockers() {
106 >        List<Function<StampedLock, Long>> writeLockers = new ArrayList<>();
107 >        writeLockers.add(sl -> sl.writeLock());
108 >        writeLockers.add(sl -> sl.tryWriteLock());
109 >        writeLockers.add(sl -> writeLockInterruptiblyUninterrupted(sl));
110 >        writeLockers.add(sl -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
111 >        writeLockers.add(sl -> tryWriteLockUninterrupted(sl, 0L, DAYS));
112 >        writeLockers.add(sl -> sl.tryConvertToWriteLock(sl.tryOptimisticRead()));
113 >        return writeLockers;
114 >    }
115 >
116 >    List<BiConsumer<StampedLock, Long>> writeUnlockers() {
117 >        List<BiConsumer<StampedLock, Long>> writeUnlockers = new ArrayList<>();
118 >        writeUnlockers.add((sl, stamp) -> sl.unlockWrite(stamp));
119 >        writeUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockWrite()));
120 >        writeUnlockers.add((sl, stamp) -> sl.asWriteLock().unlock());
121 >        writeUnlockers.add((sl, stamp) -> sl.unlock(stamp));
122 >        writeUnlockers.add((sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
123 >        return writeUnlockers;
124 >    }
125 >
126 >    /**
127 >     * Constructed StampedLock is in unlocked state
128 >     */
129 >    public void testConstructor() {
130 >        assertUnlocked(new StampedLock());
131 >    }
132 >
133 >    /**
134 >     * write-locking, then unlocking, an unlocked lock succeed
135 >     */
136 >    public void testWriteLock_lockUnlock() {
137 >        StampedLock lock = new StampedLock();
138 >
139 >        for (Function<StampedLock, Long> writeLocker : writeLockers())
140 >        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
141 >            assertFalse(lock.isWriteLocked());
142 >            assertFalse(lock.isReadLocked());
143 >            assertEquals(0, lock.getReadLockCount());
144 >
145 >            long s = writeLocker.apply(lock);
146 >            assertValid(lock, s);
147 >            assertTrue(lock.isWriteLocked());
148 >            assertFalse(lock.isReadLocked());
149 >            assertEquals(0, lock.getReadLockCount());
150 >            writeUnlocker.accept(lock, s);
151 >            assertUnlocked(lock);
152 >        }
153 >    }
154  
155 <    public void testConstructor() { new StampedLock(); }
155 >    /**
156 >     * read-locking, then unlocking, an unlocked lock succeed
157 >     */
158 >    public void testReadLock_lockUnlock() {
159 >        StampedLock lock = new StampedLock();
160 >
161 >        for (Function<StampedLock, Long> readLocker : readLockers())
162 >        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
163 >            long s = 42;
164 >            for (int i = 0; i < 2; i++) {
165 >                s = assertValid(lock, readLocker.apply(lock));
166 >                assertFalse(lock.isWriteLocked());
167 >                assertTrue(lock.isReadLocked());
168 >                assertEquals(i + 1, lock.getReadLockCount());
169 >            }
170 >            for (int i = 0; i < 2; i++) {
171 >                assertFalse(lock.isWriteLocked());
172 >                assertTrue(lock.isReadLocked());
173 >                assertEquals(2 - i, lock.getReadLockCount());
174 >                readUnlocker.accept(lock, s);
175 >            }
176 >            assertUnlocked(lock);
177 >        }
178 >    }
179  
180 < //     /**
181 < //      * A runnable calling lockInterruptibly
182 < //      */
183 < //     class InterruptibleLockRunnable extends CheckedRunnable {
184 < //         final ReentrantReadWriteLock lock;
185 < //         InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
186 < //         public void realRun() throws InterruptedException {
187 < //             lock.writeLock().lockInterruptibly();
188 < //         }
189 < //     }
190 <
191 < //     /**
192 < //      * A runnable calling lockInterruptibly that expects to be
193 < //      * interrupted
194 < //      */
195 < //     class InterruptedLockRunnable extends CheckedInterruptedRunnable {
49 < //         final ReentrantReadWriteLock lock;
50 < //         InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
51 < //         public void realRun() throws InterruptedException {
52 < //             lock.writeLock().lockInterruptibly();
53 < //         }
54 < //     }
55 <
56 < //     /**
57 < //      * Subclass to expose protected methods
58 < //      */
59 < //     static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
60 < //         PublicReentrantReadWriteLock() { super(); }
61 < //         PublicReentrantReadWriteLock(boolean fair) { super(fair); }
62 < //         public Thread getOwner() {
63 < //             return super.getOwner();
64 < //         }
65 < //         public Collection<Thread> getQueuedThreads() {
66 < //             return super.getQueuedThreads();
67 < //         }
68 < //         public Collection<Thread> getWaitingThreads(Condition c) {
69 < //             return super.getWaitingThreads(c);
70 < //         }
71 < //     }
72 <
73 < //     /**
74 < //      * Releases write lock, checking that it had a hold count of 1.
75 < //      */
76 < //     void releaseWriteLock(PublicReentrantReadWriteLock lock) {
77 < //         ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
78 < //         assertWriteLockedByMoi(lock);
79 < //         assertEquals(1, lock.getWriteHoldCount());
80 < //         writeLock.unlock();
81 < //         assertNotWriteLocked(lock);
82 < //     }
83 <
84 < //     /**
85 < //      * Spin-waits until lock.hasQueuedThread(t) becomes true.
86 < //      */
87 < //     void waitForQueuedThread(PublicReentrantReadWriteLock lock, Thread t) {
88 < //         long startTime = System.nanoTime();
89 < //         while (!lock.hasQueuedThread(t)) {
90 < //             if (millisElapsedSince(startTime) > LONG_DELAY_MS)
91 < //                 throw new AssertionFailedError("timed out");
92 < //             Thread.yield();
93 < //         }
94 < //         assertTrue(t.isAlive());
95 < //         assertTrue(lock.getOwner() != t);
96 < //     }
97 <
98 < //     /**
99 < //      * Checks that lock is not write-locked.
100 < //      */
101 < //     void assertNotWriteLocked(PublicReentrantReadWriteLock lock) {
102 < //         assertFalse(lock.isWriteLocked());
103 < //         assertFalse(lock.isWriteLockedByCurrentThread());
104 < //         assertFalse(lock.writeLock().isHeldByCurrentThread());
105 < //         assertEquals(0, lock.getWriteHoldCount());
106 < //         assertEquals(0, lock.writeLock().getHoldCount());
107 < //         assertNull(lock.getOwner());
108 < //     }
109 <
110 < //     /**
111 < //      * Checks that lock is write-locked by the given thread.
112 < //      */
113 < //     void assertWriteLockedBy(PublicReentrantReadWriteLock lock, Thread t) {
114 < //         assertTrue(lock.isWriteLocked());
115 < //         assertSame(t, lock.getOwner());
116 < //         assertEquals(t == Thread.currentThread(),
117 < //                      lock.isWriteLockedByCurrentThread());
118 < //         assertEquals(t == Thread.currentThread(),
119 < //                      lock.writeLock().isHeldByCurrentThread());
120 < //         assertEquals(t == Thread.currentThread(),
121 < //                      lock.getWriteHoldCount() > 0);
122 < //         assertEquals(t == Thread.currentThread(),
123 < //                      lock.writeLock().getHoldCount() > 0);
124 < //         assertEquals(0, lock.getReadLockCount());
125 < //     }
126 <
127 < //     /**
128 < //      * Checks that lock is write-locked by the current thread.
129 < //      */
130 < //     void assertWriteLockedByMoi(PublicReentrantReadWriteLock lock) {
131 < //         assertWriteLockedBy(lock, Thread.currentThread());
132 < //     }
133 <
134 < //     /**
135 < //      * Checks that condition c has no waiters.
136 < //      */
137 < //     void assertHasNoWaiters(PublicReentrantReadWriteLock lock, Condition c) {
138 < //         assertHasWaiters(lock, c, new Thread[] {});
139 < //     }
140 <
141 < //     /**
142 < //      * Checks that condition c has exactly the given waiter threads.
143 < //      */
144 < //     void assertHasWaiters(PublicReentrantReadWriteLock lock, Condition c,
145 < //                           Thread... threads) {
146 < //         lock.writeLock().lock();
147 < //         assertEquals(threads.length > 0, lock.hasWaiters(c));
148 < //         assertEquals(threads.length, lock.getWaitQueueLength(c));
149 < //         assertEquals(threads.length == 0, lock.getWaitingThreads(c).isEmpty());
150 < //         assertEquals(threads.length, lock.getWaitingThreads(c).size());
151 < //         assertEquals(new HashSet<Thread>(lock.getWaitingThreads(c)),
152 < //                      new HashSet<Thread>(Arrays.asList(threads)));
153 < //         lock.writeLock().unlock();
154 < //     }
155 <
156 < //     enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil };
157 <
158 < //     /**
159 < //      * Awaits condition using the specified AwaitMethod.
160 < //      */
161 < //     void await(Condition c, AwaitMethod awaitMethod)
162 < //             throws InterruptedException {
163 < //         switch (awaitMethod) {
164 < //         case await:
165 < //             c.await();
166 < //             break;
167 < //         case awaitTimed:
168 < //             assertTrue(c.await(2 * LONG_DELAY_MS, MILLISECONDS));
169 < //             break;
170 < //         case awaitNanos:
171 < //             long nanosRemaining = c.awaitNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
172 < //             assertTrue(nanosRemaining > 0);
173 < //             break;
174 < //         case awaitUntil:
175 < //             java.util.Date d = new java.util.Date();
176 < //             assertTrue(c.awaitUntil(new java.util.Date(d.getTime() + 2 * LONG_DELAY_MS)));
177 < //             break;
178 < //         }
179 < //     }
180 <
181 < //     /**
182 < //      * Constructor sets given fairness, and is in unlocked state
183 < //      */
184 < //     public void testConstructor() {
185 < //         PublicReentrantReadWriteLock lock;
186 <
187 < //         lock = new PublicReentrantReadWriteLock();
188 < //         assertFalse(lock.isFair());
189 < //         assertNotWriteLocked(lock);
190 < //         assertEquals(0, lock.getReadLockCount());
191 <
192 < //         lock = new PublicReentrantReadWriteLock(true);
193 < //         assertTrue(lock.isFair());
194 < //         assertNotWriteLocked(lock);
195 < //         assertEquals(0, lock.getReadLockCount());
196 <
197 < //         lock = new PublicReentrantReadWriteLock(false);
198 < //         assertFalse(lock.isFair());
199 < //         assertNotWriteLocked(lock);
200 < //         assertEquals(0, lock.getReadLockCount());
201 < //     }
202 <
203 < //     /**
204 < //      * write-locking and read-locking an unlocked lock succeed
205 < //      */
206 < //     public void testLock()      { testLock(false); }
207 < //     public void testLock_fair() { testLock(true); }
208 < //     public void testLock(boolean fair) {
209 < //         PublicReentrantReadWriteLock lock =
210 < //             new PublicReentrantReadWriteLock(fair);
211 < //         assertNotWriteLocked(lock);
212 < //         lock.writeLock().lock();
213 < //         assertWriteLockedByMoi(lock);
214 < //         lock.writeLock().unlock();
215 < //         assertNotWriteLocked(lock);
216 < //         assertEquals(0, lock.getReadLockCount());
217 < //         lock.readLock().lock();
218 < //         assertNotWriteLocked(lock);
219 < //         assertEquals(1, lock.getReadLockCount());
220 < //         lock.readLock().unlock();
221 < //         assertNotWriteLocked(lock);
222 < //         assertEquals(0, lock.getReadLockCount());
223 < //     }
224 <
225 < //     /**
226 < //      * getWriteHoldCount returns number of recursive holds
227 < //      */
228 < //     public void testGetWriteHoldCount()      { testGetWriteHoldCount(false); }
229 < //     public void testGetWriteHoldCount_fair() { testGetWriteHoldCount(true); }
230 < //     public void testGetWriteHoldCount(boolean fair) {
231 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
232 < //         for (int i = 1; i <= SIZE; i++) {
233 < //             lock.writeLock().lock();
234 < //             assertEquals(i,lock.getWriteHoldCount());
235 < //         }
236 < //         for (int i = SIZE; i > 0; i--) {
237 < //             lock.writeLock().unlock();
238 < //             assertEquals(i-1,lock.getWriteHoldCount());
239 < //         }
240 < //     }
241 <
242 < //     /**
243 < //      * writelock.getHoldCount returns number of recursive holds
244 < //      */
245 < //     public void testGetHoldCount()      { testGetHoldCount(false); }
246 < //     public void testGetHoldCount_fair() { testGetHoldCount(true); }
247 < //     public void testGetHoldCount(boolean fair) {
248 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
249 < //         for (int i = 1; i <= SIZE; i++) {
250 < //             lock.writeLock().lock();
251 < //             assertEquals(i,lock.writeLock().getHoldCount());
252 < //         }
253 < //         for (int i = SIZE; i > 0; i--) {
254 < //             lock.writeLock().unlock();
255 < //             assertEquals(i-1,lock.writeLock().getHoldCount());
256 < //         }
257 < //     }
258 <
259 < //     /**
260 < //      * getReadHoldCount returns number of recursive holds
261 < //      */
262 < //     public void testGetReadHoldCount()      { testGetReadHoldCount(false); }
263 < //     public void testGetReadHoldCount_fair() { testGetReadHoldCount(true); }
264 < //     public void testGetReadHoldCount(boolean fair) {
265 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
266 < //         for (int i = 1; i <= SIZE; i++) {
267 < //             lock.readLock().lock();
268 < //             assertEquals(i,lock.getReadHoldCount());
269 < //         }
270 < //         for (int i = SIZE; i > 0; i--) {
271 < //             lock.readLock().unlock();
272 < //             assertEquals(i-1,lock.getReadHoldCount());
273 < //         }
274 < //     }
275 <
276 < //     /**
277 < //      * write-unlocking an unlocked lock throws IllegalMonitorStateException
278 < //      */
279 < //     public void testWriteUnlock_IMSE()      { testWriteUnlock_IMSE(false); }
280 < //     public void testWriteUnlock_IMSE_fair() { testWriteUnlock_IMSE(true); }
281 < //     public void testWriteUnlock_IMSE(boolean fair) {
282 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
283 < //         try {
284 < //             lock.writeLock().unlock();
285 < //             shouldThrow();
286 < //         } catch (IllegalMonitorStateException success) {}
287 < //     }
288 <
289 < //     /**
290 < //      * read-unlocking an unlocked lock throws IllegalMonitorStateException
291 < //      */
292 < //     public void testReadUnlock_IMSE()      { testReadUnlock_IMSE(false); }
293 < //     public void testReadUnlock_IMSE_fair() { testReadUnlock_IMSE(true); }
294 < //     public void testReadUnlock_IMSE(boolean fair) {
295 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
296 < //         try {
297 < //             lock.readLock().unlock();
298 < //             shouldThrow();
299 < //         } catch (IllegalMonitorStateException success) {}
300 < //     }
301 <
302 < //     /**
303 < //      * write-lockInterruptibly is interruptible
304 < //      */
305 < //     public void testWriteLockInterruptibly_Interruptible()      { testWriteLockInterruptibly_Interruptible(false); }
306 < //     public void testWriteLockInterruptibly_Interruptible_fair() { testWriteLockInterruptibly_Interruptible(true); }
307 < //     public void testWriteLockInterruptibly_Interruptible(boolean fair) {
308 < //         final PublicReentrantReadWriteLock lock =
309 < //             new PublicReentrantReadWriteLock(fair);
310 < //         lock.writeLock().lock();
311 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
312 < //             public void realRun() throws InterruptedException {
313 < //                 lock.writeLock().lockInterruptibly();
314 < //             }});
315 <
316 < //         waitForQueuedThread(lock, t);
317 < //         t.interrupt();
318 < //         awaitTermination(t);
319 < //         releaseWriteLock(lock);
320 < //     }
321 <
322 < //     /**
323 < //      * timed write-tryLock is interruptible
324 < //      */
325 < //     public void testWriteTryLock_Interruptible()      { testWriteTryLock_Interruptible(false); }
326 < //     public void testWriteTryLock_Interruptible_fair() { testWriteTryLock_Interruptible(true); }
327 < //     public void testWriteTryLock_Interruptible(boolean fair) {
328 < //         final PublicReentrantReadWriteLock lock =
329 < //             new PublicReentrantReadWriteLock(fair);
330 < //         lock.writeLock().lock();
331 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
332 < //             public void realRun() throws InterruptedException {
333 < //                 lock.writeLock().tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
334 < //             }});
335 <
336 < //         waitForQueuedThread(lock, t);
337 < //         t.interrupt();
338 < //         awaitTermination(t);
339 < //         releaseWriteLock(lock);
340 < //     }
341 <
342 < //     /**
343 < //      * read-lockInterruptibly is interruptible
344 < //      */
345 < //     public void testReadLockInterruptibly_Interruptible()      { testReadLockInterruptibly_Interruptible(false); }
346 < //     public void testReadLockInterruptibly_Interruptible_fair() { testReadLockInterruptibly_Interruptible(true); }
347 < //     public void testReadLockInterruptibly_Interruptible(boolean fair) {
348 < //         final PublicReentrantReadWriteLock lock =
349 < //             new PublicReentrantReadWriteLock(fair);
350 < //         lock.writeLock().lock();
351 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
352 < //             public void realRun() throws InterruptedException {
353 < //                 lock.readLock().lockInterruptibly();
354 < //             }});
355 <
356 < //         waitForQueuedThread(lock, t);
357 < //         t.interrupt();
358 < //         awaitTermination(t);
359 < //         releaseWriteLock(lock);
360 < //     }
361 <
362 < //     /**
363 < //      * timed read-tryLock is interruptible
364 < //      */
365 < //     public void testReadTryLock_Interruptible()      { testReadTryLock_Interruptible(false); }
366 < //     public void testReadTryLock_Interruptible_fair() { testReadTryLock_Interruptible(true); }
367 < //     public void testReadTryLock_Interruptible(boolean fair) {
368 < //         final PublicReentrantReadWriteLock lock =
369 < //             new PublicReentrantReadWriteLock(fair);
370 < //         lock.writeLock().lock();
371 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
372 < //             public void realRun() throws InterruptedException {
373 < //                 lock.readLock().tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
374 < //             }});
375 <
376 < //         waitForQueuedThread(lock, t);
377 < //         t.interrupt();
378 < //         awaitTermination(t);
379 < //         releaseWriteLock(lock);
380 < //     }
381 <
382 < //     /**
383 < //      * write-tryLock on an unlocked lock succeeds
384 < //      */
385 < //     public void testWriteTryLock()      { testWriteTryLock(false); }
386 < //     public void testWriteTryLock_fair() { testWriteTryLock(true); }
387 < //     public void testWriteTryLock(boolean fair) {
388 < //         final PublicReentrantReadWriteLock lock =
389 < //             new PublicReentrantReadWriteLock(fair);
390 < //         assertTrue(lock.writeLock().tryLock());
391 < //         assertWriteLockedByMoi(lock);
392 < //         assertTrue(lock.writeLock().tryLock());
393 < //         assertWriteLockedByMoi(lock);
394 < //         lock.writeLock().unlock();
395 < //         releaseWriteLock(lock);
396 < //     }
397 <
398 < //     /**
399 < //      * write-tryLock fails if locked
400 < //      */
401 < //     public void testWriteTryLockWhenLocked()      { testWriteTryLockWhenLocked(false); }
402 < //     public void testWriteTryLockWhenLocked_fair() { testWriteTryLockWhenLocked(true); }
403 < //     public void testWriteTryLockWhenLocked(boolean fair) {
404 < //         final PublicReentrantReadWriteLock lock =
405 < //             new PublicReentrantReadWriteLock(fair);
406 < //         lock.writeLock().lock();
407 < //         Thread t = newStartedThread(new CheckedRunnable() {
408 < //             public void realRun() {
409 < //                 assertFalse(lock.writeLock().tryLock());
410 < //             }});
411 <
412 < //         awaitTermination(t);
413 < //         releaseWriteLock(lock);
414 < //     }
415 <
416 < //     /**
417 < //      * read-tryLock fails if locked
418 < //      */
419 < //     public void testReadTryLockWhenLocked()      { testReadTryLockWhenLocked(false); }
420 < //     public void testReadTryLockWhenLocked_fair() { testReadTryLockWhenLocked(true); }
421 < //     public void testReadTryLockWhenLocked(boolean fair) {
422 < //         final PublicReentrantReadWriteLock lock =
423 < //             new PublicReentrantReadWriteLock(fair);
424 < //         lock.writeLock().lock();
425 < //         Thread t = newStartedThread(new CheckedRunnable() {
426 < //             public void realRun() {
427 < //                 assertFalse(lock.readLock().tryLock());
428 < //             }});
429 <
430 < //         awaitTermination(t);
431 < //         releaseWriteLock(lock);
432 < //     }
433 <
434 < //     /**
435 < //      * Multiple threads can hold a read lock when not write-locked
436 < //      */
437 < //     public void testMultipleReadLocks()      { testMultipleReadLocks(false); }
438 < //     public void testMultipleReadLocks_fair() { testMultipleReadLocks(true); }
439 < //     public void testMultipleReadLocks(boolean fair) {
440 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
441 < //         lock.readLock().lock();
442 < //         Thread t = newStartedThread(new CheckedRunnable() {
443 < //             public void realRun() throws InterruptedException {
444 < //                 assertTrue(lock.readLock().tryLock());
445 < //                 lock.readLock().unlock();
446 < //                 assertTrue(lock.readLock().tryLock(LONG_DELAY_MS, MILLISECONDS));
447 < //                 lock.readLock().unlock();
448 < //                 lock.readLock().lock();
449 < //                 lock.readLock().unlock();
450 < //             }});
451 <
452 < //         awaitTermination(t);
453 < //         lock.readLock().unlock();
454 < //     }
455 <
456 < //     /**
457 < //      * A writelock succeeds only after a reading thread unlocks
458 < //      */
459 < //     public void testWriteAfterReadLock()      { testWriteAfterReadLock(false); }
460 < //     public void testWriteAfterReadLock_fair() { testWriteAfterReadLock(true); }
461 < //     public void testWriteAfterReadLock(boolean fair) {
462 < //         final PublicReentrantReadWriteLock lock =
463 < //             new PublicReentrantReadWriteLock(fair);
464 < //         lock.readLock().lock();
465 < //         Thread t = newStartedThread(new CheckedRunnable() {
466 < //             public void realRun() {
467 < //                 assertEquals(1, lock.getReadLockCount());
468 < //                 lock.writeLock().lock();
469 < //                 assertEquals(0, lock.getReadLockCount());
470 < //                 lock.writeLock().unlock();
471 < //             }});
472 < //         waitForQueuedThread(lock, t);
473 < //         assertNotWriteLocked(lock);
474 < //         assertEquals(1, lock.getReadLockCount());
475 < //         lock.readLock().unlock();
476 < //         assertEquals(0, lock.getReadLockCount());
477 < //         awaitTermination(t);
478 < //         assertNotWriteLocked(lock);
479 < //     }
480 <
481 < //     /**
482 < //      * A writelock succeeds only after reading threads unlock
483 < //      */
484 < //     public void testWriteAfterMultipleReadLocks()      { testWriteAfterMultipleReadLocks(false); }
485 < //     public void testWriteAfterMultipleReadLocks_fair() { testWriteAfterMultipleReadLocks(true); }
486 < //     public void testWriteAfterMultipleReadLocks(boolean fair) {
487 < //         final PublicReentrantReadWriteLock lock =
488 < //             new PublicReentrantReadWriteLock(fair);
489 < //         lock.readLock().lock();
490 < //         lock.readLock().lock();
491 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
492 < //             public void realRun() {
493 < //                 lock.readLock().lock();
494 < //                 assertEquals(3, lock.getReadLockCount());
495 < //                 lock.readLock().unlock();
496 < //             }});
497 < //         awaitTermination(t1);
498 <
499 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
500 < //             public void realRun() {
501 < //                 assertEquals(2, lock.getReadLockCount());
502 < //                 lock.writeLock().lock();
503 < //                 assertEquals(0, lock.getReadLockCount());
504 < //                 lock.writeLock().unlock();
505 < //             }});
506 < //         waitForQueuedThread(lock, t2);
507 < //         assertNotWriteLocked(lock);
508 < //         assertEquals(2, lock.getReadLockCount());
509 < //         lock.readLock().unlock();
510 < //         lock.readLock().unlock();
511 < //         assertEquals(0, lock.getReadLockCount());
512 < //         awaitTermination(t2);
513 < //         assertNotWriteLocked(lock);
514 < //     }
515 <
516 < //     /**
517 < //      * A thread that tries to acquire a fair read lock (non-reentrantly)
518 < //      * will block if there is a waiting writer thread
519 < //      */
520 < //     public void testReaderWriterReaderFairFifo() {
521 < //         final PublicReentrantReadWriteLock lock =
522 < //             new PublicReentrantReadWriteLock(true);
523 < //         final AtomicBoolean t1GotLock = new AtomicBoolean(false);
524 <
525 < //         lock.readLock().lock();
526 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
527 < //             public void realRun() {
528 < //                 assertEquals(1, lock.getReadLockCount());
529 < //                 lock.writeLock().lock();
530 < //                 assertEquals(0, lock.getReadLockCount());
531 < //                 t1GotLock.set(true);
532 < //                 lock.writeLock().unlock();
533 < //             }});
534 < //         waitForQueuedThread(lock, t1);
535 <
536 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
537 < //             public void realRun() {
538 < //                 assertEquals(1, lock.getReadLockCount());
539 < //                 lock.readLock().lock();
540 < //                 assertEquals(1, lock.getReadLockCount());
541 < //                 assertTrue(t1GotLock.get());
542 < //                 lock.readLock().unlock();
543 < //             }});
544 < //         waitForQueuedThread(lock, t2);
545 < //         assertTrue(t1.isAlive());
546 < //         assertNotWriteLocked(lock);
547 < //         assertEquals(1, lock.getReadLockCount());
548 < //         lock.readLock().unlock();
549 < //         awaitTermination(t1);
550 < //         awaitTermination(t2);
551 < //         assertNotWriteLocked(lock);
552 < //     }
553 <
554 < //     /**
555 < //      * Readlocks succeed only after a writing thread unlocks
556 < //      */
557 < //     public void testReadAfterWriteLock()      { testReadAfterWriteLock(false); }
558 < //     public void testReadAfterWriteLock_fair() { testReadAfterWriteLock(true); }
559 < //     public void testReadAfterWriteLock(boolean fair) {
560 < //         final PublicReentrantReadWriteLock lock =
561 < //             new PublicReentrantReadWriteLock(fair);
562 < //         lock.writeLock().lock();
563 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
564 < //             public void realRun() {
565 < //                 lock.readLock().lock();
566 < //                 lock.readLock().unlock();
567 < //             }});
568 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
569 < //             public void realRun() {
570 < //                 lock.readLock().lock();
571 < //                 lock.readLock().unlock();
572 < //             }});
573 <
574 < //         waitForQueuedThread(lock, t1);
575 < //         waitForQueuedThread(lock, t2);
576 < //         releaseWriteLock(lock);
577 < //         awaitTermination(t1);
578 < //         awaitTermination(t2);
579 < //     }
580 <
581 < //     /**
582 < //      * Read trylock succeeds if write locked by current thread
583 < //      */
584 < //     public void testReadHoldingWriteLock()      { testReadHoldingWriteLock(false); }
585 < //     public void testReadHoldingWriteLock_fair() { testReadHoldingWriteLock(true); }
586 < //     public void testReadHoldingWriteLock(boolean fair) {
587 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
588 < //         lock.writeLock().lock();
589 < //         assertTrue(lock.readLock().tryLock());
590 < //         lock.readLock().unlock();
591 < //         lock.writeLock().unlock();
592 < //     }
593 <
594 < //     /**
595 < //      * Read trylock succeeds (barging) even in the presence of waiting
596 < //      * readers and/or writers
597 < //      */
598 < //     public void testReadTryLockBarging()      { testReadTryLockBarging(false); }
599 < //     public void testReadTryLockBarging_fair() { testReadTryLockBarging(true); }
600 < //     public void testReadTryLockBarging(boolean fair) {
601 < //         final PublicReentrantReadWriteLock lock =
602 < //             new PublicReentrantReadWriteLock(fair);
603 < //         lock.readLock().lock();
604 <
605 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
606 < //             public void realRun() {
607 < //                 lock.writeLock().lock();
608 < //                 lock.writeLock().unlock();
609 < //             }});
610 <
611 < //         waitForQueuedThread(lock, t1);
612 <
613 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
614 < //             public void realRun() {
615 < //                 lock.readLock().lock();
616 < //                 lock.readLock().unlock();
617 < //             }});
618 <
619 < //         if (fair)
620 < //             waitForQueuedThread(lock, t2);
621 <
622 < //         Thread t3 = newStartedThread(new CheckedRunnable() {
623 < //             public void realRun() {
624 < //                 lock.readLock().tryLock();
625 < //                 lock.readLock().unlock();
626 < //             }});
627 <
628 < //         assertTrue(lock.getReadLockCount() > 0);
629 < //         awaitTermination(t3);
630 < //         assertTrue(t1.isAlive());
631 < //         if (fair) assertTrue(t2.isAlive());
632 < //         lock.readLock().unlock();
633 < //         awaitTermination(t1);
634 < //         awaitTermination(t2);
635 < //     }
636 <
637 < //     /**
638 < //      * Read lock succeeds if write locked by current thread even if
639 < //      * other threads are waiting for readlock
640 < //      */
641 < //     public void testReadHoldingWriteLock2()      { testReadHoldingWriteLock2(false); }
642 < //     public void testReadHoldingWriteLock2_fair() { testReadHoldingWriteLock2(true); }
643 < //     public void testReadHoldingWriteLock2(boolean fair) {
644 < //         final PublicReentrantReadWriteLock lock =
645 < //             new PublicReentrantReadWriteLock(fair);
646 < //         lock.writeLock().lock();
647 < //         lock.readLock().lock();
648 < //         lock.readLock().unlock();
649 <
650 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
651 < //             public void realRun() {
652 < //                 lock.readLock().lock();
653 < //                 lock.readLock().unlock();
654 < //             }});
655 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
656 < //             public void realRun() {
657 < //                 lock.readLock().lock();
658 < //                 lock.readLock().unlock();
659 < //             }});
660 <
661 < //         waitForQueuedThread(lock, t1);
662 < //         waitForQueuedThread(lock, t2);
663 < //         assertWriteLockedByMoi(lock);
664 < //         lock.readLock().lock();
665 < //         lock.readLock().unlock();
666 < //         releaseWriteLock(lock);
667 < //         awaitTermination(t1);
668 < //         awaitTermination(t2);
669 < //     }
670 <
671 < //     /**
672 < //      * Read lock succeeds if write locked by current thread even if
673 < //      * other threads are waiting for writelock
674 < //      */
675 < //     public void testReadHoldingWriteLock3()      { testReadHoldingWriteLock3(false); }
676 < //     public void testReadHoldingWriteLock3_fair() { testReadHoldingWriteLock3(true); }
677 < //     public void testReadHoldingWriteLock3(boolean fair) {
678 < //         final PublicReentrantReadWriteLock lock =
679 < //             new PublicReentrantReadWriteLock(fair);
680 < //         lock.writeLock().lock();
681 < //         lock.readLock().lock();
682 < //         lock.readLock().unlock();
683 <
684 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
685 < //             public void realRun() {
686 < //                 lock.writeLock().lock();
687 < //                 lock.writeLock().unlock();
688 < //             }});
689 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
690 < //             public void realRun() {
691 < //                 lock.writeLock().lock();
692 < //                 lock.writeLock().unlock();
693 < //             }});
694 <
695 < //         waitForQueuedThread(lock, t1);
696 < //         waitForQueuedThread(lock, t2);
697 < //         assertWriteLockedByMoi(lock);
698 < //         lock.readLock().lock();
699 < //         lock.readLock().unlock();
700 < //         assertWriteLockedByMoi(lock);
701 < //         lock.writeLock().unlock();
702 < //         awaitTermination(t1);
703 < //         awaitTermination(t2);
704 < //     }
705 <
706 < //     /**
707 < //      * Write lock succeeds if write locked by current thread even if
708 < //      * other threads are waiting for writelock
709 < //      */
710 < //     public void testWriteHoldingWriteLock4()      { testWriteHoldingWriteLock4(false); }
711 < //     public void testWriteHoldingWriteLock4_fair() { testWriteHoldingWriteLock4(true); }
712 < //     public void testWriteHoldingWriteLock4(boolean fair) {
713 < //         final PublicReentrantReadWriteLock lock =
714 < //             new PublicReentrantReadWriteLock(fair);
715 < //         lock.writeLock().lock();
716 < //         lock.writeLock().lock();
717 < //         lock.writeLock().unlock();
718 <
719 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
720 < //             public void realRun() {
721 < //                 lock.writeLock().lock();
722 < //                 lock.writeLock().unlock();
723 < //             }});
724 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
725 < //             public void realRun() {
726 < //                 lock.writeLock().lock();
727 < //                 lock.writeLock().unlock();
728 < //             }});
729 <
730 < //         waitForQueuedThread(lock, t1);
731 < //         waitForQueuedThread(lock, t2);
732 < //         assertWriteLockedByMoi(lock);
733 < //         assertEquals(1, lock.getWriteHoldCount());
734 < //         lock.writeLock().lock();
735 < //         assertWriteLockedByMoi(lock);
736 < //         assertEquals(2, lock.getWriteHoldCount());
737 < //         lock.writeLock().unlock();
738 < //         assertWriteLockedByMoi(lock);
739 < //         assertEquals(1, lock.getWriteHoldCount());
740 < //         lock.writeLock().unlock();
741 < //         awaitTermination(t1);
742 < //         awaitTermination(t2);
743 < //     }
744 <
745 < //     /**
746 < //      * Read tryLock succeeds if readlocked but not writelocked
747 < //      */
748 < //     public void testTryLockWhenReadLocked()      { testTryLockWhenReadLocked(false); }
749 < //     public void testTryLockWhenReadLocked_fair() { testTryLockWhenReadLocked(true); }
750 < //     public void testTryLockWhenReadLocked(boolean fair) {
751 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
752 < //         lock.readLock().lock();
753 < //         Thread t = newStartedThread(new CheckedRunnable() {
754 < //             public void realRun() {
755 < //                 assertTrue(lock.readLock().tryLock());
756 < //                 lock.readLock().unlock();
757 < //             }});
758 <
759 < //         awaitTermination(t);
760 < //         lock.readLock().unlock();
761 < //     }
762 <
763 < //     /**
764 < //      * write tryLock fails when readlocked
765 < //      */
766 < //     public void testWriteTryLockWhenReadLocked()      { testWriteTryLockWhenReadLocked(false); }
767 < //     public void testWriteTryLockWhenReadLocked_fair() { testWriteTryLockWhenReadLocked(true); }
768 < //     public void testWriteTryLockWhenReadLocked(boolean fair) {
769 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
770 < //         lock.readLock().lock();
771 < //         Thread t = newStartedThread(new CheckedRunnable() {
772 < //             public void realRun() {
773 < //                 assertFalse(lock.writeLock().tryLock());
774 < //             }});
775 <
776 < //         awaitTermination(t);
777 < //         lock.readLock().unlock();
778 < //     }
779 <
780 < //     /**
781 < //      * write timed tryLock times out if locked
782 < //      */
783 < //     public void testWriteTryLock_Timeout()      { testWriteTryLock_Timeout(false); }
784 < //     public void testWriteTryLock_Timeout_fair() { testWriteTryLock_Timeout(true); }
785 < //     public void testWriteTryLock_Timeout(boolean fair) {
786 < //         final PublicReentrantReadWriteLock lock =
787 < //             new PublicReentrantReadWriteLock(fair);
788 < //         lock.writeLock().lock();
789 < //         Thread t = newStartedThread(new CheckedRunnable() {
790 < //             public void realRun() throws InterruptedException {
791 < //                 long startTime = System.nanoTime();
792 < //                 long timeoutMillis = 10;
793 < //                 assertFalse(lock.writeLock().tryLock(timeoutMillis, MILLISECONDS));
794 < //                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
795 < //             }});
796 <
797 < //         awaitTermination(t);
798 < //         releaseWriteLock(lock);
799 < //     }
800 <
801 < //     /**
802 < //      * read timed tryLock times out if write-locked
803 < //      */
804 < //     public void testReadTryLock_Timeout()      { testReadTryLock_Timeout(false); }
805 < //     public void testReadTryLock_Timeout_fair() { testReadTryLock_Timeout(true); }
806 < //     public void testReadTryLock_Timeout(boolean fair) {
807 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
808 < //         lock.writeLock().lock();
809 < //         Thread t = newStartedThread(new CheckedRunnable() {
810 < //             public void realRun() throws InterruptedException {
811 < //                 long startTime = System.nanoTime();
812 < //                 long timeoutMillis = 10;
813 < //                 assertFalse(lock.readLock().tryLock(timeoutMillis, MILLISECONDS));
814 < //                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
815 < //             }});
816 <
817 < //         awaitTermination(t);
818 < //         assertTrue(lock.writeLock().isHeldByCurrentThread());
819 < //         lock.writeLock().unlock();
820 < //     }
821 <
822 < //     /**
823 < //      * write lockInterruptibly succeeds if unlocked, else is interruptible
824 < //      */
825 < //     public void testWriteLockInterruptibly()      { testWriteLockInterruptibly(false); }
826 < //     public void testWriteLockInterruptibly_fair() { testWriteLockInterruptibly(true); }
827 < //     public void testWriteLockInterruptibly(boolean fair) {
828 < //         final PublicReentrantReadWriteLock lock =
829 < //             new PublicReentrantReadWriteLock(fair);
830 < //         try {
831 < //             lock.writeLock().lockInterruptibly();
832 < //         } catch (InterruptedException ie) {
833 < //             threadUnexpectedException(ie);
834 < //         }
835 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
836 < //             public void realRun() throws InterruptedException {
837 < //                 lock.writeLock().lockInterruptibly();
838 < //             }});
839 <
840 < //         waitForQueuedThread(lock, t);
841 < //         t.interrupt();
842 < //         assertTrue(lock.writeLock().isHeldByCurrentThread());
843 < //         awaitTermination(t);
844 < //         releaseWriteLock(lock);
845 < //     }
846 <
847 < //     /**
848 < //      * read lockInterruptibly succeeds if lock free else is interruptible
849 < //      */
850 < //     public void testReadLockInterruptibly()      { testReadLockInterruptibly(false); }
851 < //     public void testReadLockInterruptibly_fair() { testReadLockInterruptibly(true); }
852 < //     public void testReadLockInterruptibly(boolean fair) {
853 < //         final PublicReentrantReadWriteLock lock =
854 < //             new PublicReentrantReadWriteLock(fair);
855 < //         try {
856 < //             lock.readLock().lockInterruptibly();
857 < //             lock.readLock().unlock();
858 < //             lock.writeLock().lockInterruptibly();
859 < //         } catch (InterruptedException ie) {
860 < //             threadUnexpectedException(ie);
861 < //         }
862 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
863 < //             public void realRun() throws InterruptedException {
864 < //                 lock.readLock().lockInterruptibly();
865 < //             }});
866 <
867 < //         waitForQueuedThread(lock, t);
868 < //         t.interrupt();
869 < //         awaitTermination(t);
870 < //         releaseWriteLock(lock);
871 < //     }
872 <
873 < //     /**
874 < //      * Calling await without holding lock throws IllegalMonitorStateException
875 < //      */
876 < //     public void testAwait_IMSE()      { testAwait_IMSE(false); }
877 < //     public void testAwait_IMSE_fair() { testAwait_IMSE(true); }
878 < //     public void testAwait_IMSE(boolean fair) {
879 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
880 < //         final Condition c = lock.writeLock().newCondition();
881 < //         for (AwaitMethod awaitMethod : AwaitMethod.values()) {
882 < //             long startTime = System.nanoTime();
883 < //             try {
884 < //                 await(c, awaitMethod);
885 < //                 shouldThrow();
886 < //             } catch (IllegalMonitorStateException success) {
887 < //             } catch (InterruptedException e) { threadUnexpectedException(e); }
888 < //             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
889 < //         }
890 < //     }
891 <
892 < //     /**
893 < //      * Calling signal without holding lock throws IllegalMonitorStateException
894 < //      */
895 < //     public void testSignal_IMSE()      { testSignal_IMSE(false); }
896 < //     public void testSignal_IMSE_fair() { testSignal_IMSE(true); }
897 < //     public void testSignal_IMSE(boolean fair) {
898 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
899 < //         final Condition c = lock.writeLock().newCondition();
900 < //         try {
901 < //             c.signal();
902 < //             shouldThrow();
903 < //         } catch (IllegalMonitorStateException success) {}
904 < //     }
905 <
906 < //     /**
907 < //      * Calling signalAll without holding lock throws IllegalMonitorStateException
908 < //      */
909 < //     public void testSignalAll_IMSE()      { testSignalAll_IMSE(false); }
910 < //     public void testSignalAll_IMSE_fair() { testSignalAll_IMSE(true); }
911 < //     public void testSignalAll_IMSE(boolean fair) {
912 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
913 < //         final Condition c = lock.writeLock().newCondition();
914 < //         try {
915 < //             c.signalAll();
916 < //             shouldThrow();
917 < //         } catch (IllegalMonitorStateException success) {}
918 < //     }
919 <
920 < //     /**
921 < //      * awaitNanos without a signal times out
922 < //      */
923 < //     public void testAwaitNanos_Timeout()      { testAwaitNanos_Timeout(false); }
924 < //     public void testAwaitNanos_Timeout_fair() { testAwaitNanos_Timeout(true); }
925 < //     public void testAwaitNanos_Timeout(boolean fair) {
926 < //         try {
927 < //             final ReentrantReadWriteLock lock =
928 < //                 new ReentrantReadWriteLock(fair);
929 < //             final Condition c = lock.writeLock().newCondition();
930 < //             lock.writeLock().lock();
931 < //             long startTime = System.nanoTime();
932 < //             long timeoutMillis = 10;
933 < //             long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
934 < //             long nanosRemaining = c.awaitNanos(timeoutNanos);
935 < //             assertTrue(nanosRemaining <= 0);
936 < //             assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
937 < //             lock.writeLock().unlock();
938 < //         } catch (InterruptedException e) {
939 < //             threadUnexpectedException(e);
940 < //         }
941 < //     }
942 <
943 < //     /**
944 < //      * timed await without a signal times out
945 < //      */
946 < //     public void testAwait_Timeout()      { testAwait_Timeout(false); }
947 < //     public void testAwait_Timeout_fair() { testAwait_Timeout(true); }
948 < //     public void testAwait_Timeout(boolean fair) {
949 < //         try {
950 < //             final ReentrantReadWriteLock lock =
951 < //                 new ReentrantReadWriteLock(fair);
952 < //             final Condition c = lock.writeLock().newCondition();
953 < //             lock.writeLock().lock();
954 < //             long startTime = System.nanoTime();
955 < //             long timeoutMillis = 10;
956 < //             assertFalse(c.await(timeoutMillis, MILLISECONDS));
957 < //             assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
958 < //             lock.writeLock().unlock();
959 < //         } catch (InterruptedException e) {
960 < //             threadUnexpectedException(e);
961 < //         }
962 < //     }
963 <
964 < //     /**
965 < //      * awaitUntil without a signal times out
966 < //      */
967 < //     public void testAwaitUntil_Timeout()      { testAwaitUntil_Timeout(false); }
968 < //     public void testAwaitUntil_Timeout_fair() { testAwaitUntil_Timeout(true); }
969 < //     public void testAwaitUntil_Timeout(boolean fair) {
970 < //         try {
971 < //             final ReentrantReadWriteLock lock =
972 < //                 new ReentrantReadWriteLock(fair);
973 < //             final Condition c = lock.writeLock().newCondition();
974 < //             lock.writeLock().lock();
975 < //             long startTime = System.nanoTime();
976 < //             long timeoutMillis = 10;
977 < //             java.util.Date d = new java.util.Date();
978 < //             assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + timeoutMillis)));
979 < //             assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
980 < //             lock.writeLock().unlock();
981 < //         } catch (InterruptedException e) {
982 < //             threadUnexpectedException(e);
983 < //         }
984 < //     }
985 <
986 < //     /**
987 < //      * await returns when signalled
988 < //      */
989 < //     public void testAwait()      { testAwait(false); }
990 < //     public void testAwait_fair() { testAwait(true); }
991 < //     public void testAwait(boolean fair) {
992 < //         final PublicReentrantReadWriteLock lock =
993 < //             new PublicReentrantReadWriteLock(fair);
994 < //         final Condition c = lock.writeLock().newCondition();
995 < //         final CountDownLatch locked = new CountDownLatch(1);
996 < //         Thread t = newStartedThread(new CheckedRunnable() {
997 < //             public void realRun() throws InterruptedException {
998 < //                 lock.writeLock().lock();
999 < //                 locked.countDown();
1000 < //                 c.await();
1001 < //                 lock.writeLock().unlock();
1002 < //             }});
1003 <
1004 < //         await(locked);
1005 < //         lock.writeLock().lock();
1006 < //         assertHasWaiters(lock, c, t);
1007 < //         c.signal();
1008 < //         assertHasNoWaiters(lock, c);
1009 < //         assertTrue(t.isAlive());
1010 < //         lock.writeLock().unlock();
1011 < //         awaitTermination(t);
1012 < //     }
1013 <
1014 < //     /**
1015 < //      * awaitUninterruptibly is uninterruptible
1016 < //      */
1017 < //     public void testAwaitUninterruptibly()      { testAwaitUninterruptibly(false); }
1018 < //     public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
1019 < //     public void testAwaitUninterruptibly(boolean fair) {
1020 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1021 < //         final Condition c = lock.writeLock().newCondition();
1022 < //         final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
1023 <
1024 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
1025 < //             public void realRun() {
1026 < //                 // Interrupt before awaitUninterruptibly
1027 < //                 lock.writeLock().lock();
1028 < //                 pleaseInterrupt.countDown();
1029 < //                 Thread.currentThread().interrupt();
1030 < //                 c.awaitUninterruptibly();
1031 < //                 assertTrue(Thread.interrupted());
1032 < //                 lock.writeLock().unlock();
1033 < //             }});
1034 <
1035 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
1036 < //             public void realRun() {
1037 < //                 // Interrupt during awaitUninterruptibly
1038 < //                 lock.writeLock().lock();
1039 < //                 pleaseInterrupt.countDown();
1040 < //                 c.awaitUninterruptibly();
1041 < //                 assertTrue(Thread.interrupted());
1042 < //                 lock.writeLock().unlock();
1043 < //             }});
1044 <
1045 < //         await(pleaseInterrupt);
1046 < //         lock.writeLock().lock();
1047 < //         lock.writeLock().unlock();
1048 < //         t2.interrupt();
1049 <
1050 < //         assertThreadStaysAlive(t1);
1051 < //         assertTrue(t2.isAlive());
1052 <
1053 < //         lock.writeLock().lock();
1054 < //         c.signalAll();
1055 < //         lock.writeLock().unlock();
1056 <
1057 < //         awaitTermination(t1);
1058 < //         awaitTermination(t2);
1059 < //     }
1060 <
1061 < //     /**
1062 < //      * await/awaitNanos/awaitUntil is interruptible
1063 < //      */
1064 < //     public void testInterruptible_await()           { testInterruptible(false, AwaitMethod.await); }
1065 < //     public void testInterruptible_await_fair()      { testInterruptible(true,  AwaitMethod.await); }
1066 < //     public void testInterruptible_awaitTimed()      { testInterruptible(false, AwaitMethod.awaitTimed); }
1067 < //     public void testInterruptible_awaitTimed_fair() { testInterruptible(true,  AwaitMethod.awaitTimed); }
1068 < //     public void testInterruptible_awaitNanos()      { testInterruptible(false, AwaitMethod.awaitNanos); }
1069 < //     public void testInterruptible_awaitNanos_fair() { testInterruptible(true,  AwaitMethod.awaitNanos); }
1070 < //     public void testInterruptible_awaitUntil()      { testInterruptible(false, AwaitMethod.awaitUntil); }
1071 < //     public void testInterruptible_awaitUntil_fair() { testInterruptible(true,  AwaitMethod.awaitUntil); }
1072 < //     public void testInterruptible(boolean fair, final AwaitMethod awaitMethod) {
1073 < //         final PublicReentrantReadWriteLock lock =
1074 < //             new PublicReentrantReadWriteLock(fair);
1075 < //         final Condition c = lock.writeLock().newCondition();
1076 < //         final CountDownLatch locked = new CountDownLatch(1);
1077 < //         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1078 < //             public void realRun() throws InterruptedException {
1079 < //                 lock.writeLock().lock();
1080 < //                 assertWriteLockedByMoi(lock);
1081 < //                 assertHasNoWaiters(lock, c);
1082 < //                 locked.countDown();
1083 < //                 try {
1084 < //                     await(c, awaitMethod);
1085 < //                 } finally {
1086 < //                     assertWriteLockedByMoi(lock);
1087 < //                     assertHasNoWaiters(lock, c);
1088 < //                     lock.writeLock().unlock();
1089 < //                     assertFalse(Thread.interrupted());
1090 < //                 }
1091 < //             }});
1092 <
1093 < //         await(locked);
1094 < //         assertHasWaiters(lock, c, t);
1095 < //         t.interrupt();
1096 < //         awaitTermination(t);
1097 < //         assertNotWriteLocked(lock);
1098 < //     }
1099 <
1100 < //     /**
1101 < //      * signalAll wakes up all threads
1102 < //      */
1103 < //     public void testSignalAll_await()           { testSignalAll(false, AwaitMethod.await); }
1104 < //     public void testSignalAll_await_fair()      { testSignalAll(true,  AwaitMethod.await); }
1105 < //     public void testSignalAll_awaitTimed()      { testSignalAll(false, AwaitMethod.awaitTimed); }
1106 < //     public void testSignalAll_awaitTimed_fair() { testSignalAll(true,  AwaitMethod.awaitTimed); }
1107 < //     public void testSignalAll_awaitNanos()      { testSignalAll(false, AwaitMethod.awaitNanos); }
1108 < //     public void testSignalAll_awaitNanos_fair() { testSignalAll(true,  AwaitMethod.awaitNanos); }
1109 < //     public void testSignalAll_awaitUntil()      { testSignalAll(false, AwaitMethod.awaitUntil); }
1110 < //     public void testSignalAll_awaitUntil_fair() { testSignalAll(true,  AwaitMethod.awaitUntil); }
1111 < //     public void testSignalAll(boolean fair, final AwaitMethod awaitMethod) {
1112 < //         final PublicReentrantReadWriteLock lock =
1113 < //             new PublicReentrantReadWriteLock(fair);
1114 < //         final Condition c = lock.writeLock().newCondition();
1115 < //         final CountDownLatch locked = new CountDownLatch(2);
1116 < //         final Lock writeLock = lock.writeLock();
1117 < //         class Awaiter extends CheckedRunnable {
1118 < //             public void realRun() throws InterruptedException {
1119 < //                 writeLock.lock();
1120 < //                 locked.countDown();
1121 < //                 await(c, awaitMethod);
1122 < //                 writeLock.unlock();
1123 < //             }
1124 < //         }
1125 <
1126 < //         Thread t1 = newStartedThread(new Awaiter());
1127 < //         Thread t2 = newStartedThread(new Awaiter());
1128 <
1129 < //         await(locked);
1130 < //         writeLock.lock();
1131 < //         assertHasWaiters(lock, c, t1, t2);
1132 < //         c.signalAll();
1133 < //         assertHasNoWaiters(lock, c);
1134 < //         writeLock.unlock();
1135 < //         awaitTermination(t1);
1136 < //         awaitTermination(t2);
1137 < //     }
1138 <
1139 < //     /**
1140 < //      * signal wakes up waiting threads in FIFO order
1141 < //      */
1142 < //     public void testSignalWakesFifo()      { testSignalWakesFifo(false); }
1143 < //     public void testSignalWakesFifo_fair() { testSignalWakesFifo(true); }
1144 < //     public void testSignalWakesFifo(boolean fair) {
1145 < //         final PublicReentrantReadWriteLock lock =
1146 < //             new PublicReentrantReadWriteLock(fair);
1147 < //         final Condition c = lock.writeLock().newCondition();
1148 < //         final CountDownLatch locked1 = new CountDownLatch(1);
1149 < //         final CountDownLatch locked2 = new CountDownLatch(1);
1150 < //         final Lock writeLock = lock.writeLock();
1151 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
1152 < //             public void realRun() throws InterruptedException {
1153 < //                 writeLock.lock();
1154 < //                 locked1.countDown();
1155 < //                 c.await();
1156 < //                 writeLock.unlock();
1157 < //             }});
1158 <
1159 < //         await(locked1);
1160 <
1161 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
1162 < //             public void realRun() throws InterruptedException {
1163 < //                 writeLock.lock();
1164 < //                 locked2.countDown();
1165 < //                 c.await();
1166 < //                 writeLock.unlock();
1167 < //             }});
1168 <
1169 < //         await(locked2);
1170 <
1171 < //         writeLock.lock();
1172 < //         assertHasWaiters(lock, c, t1, t2);
1173 < //         assertFalse(lock.hasQueuedThreads());
1174 < //         c.signal();
1175 < //         assertHasWaiters(lock, c, t2);
1176 < //         assertTrue(lock.hasQueuedThread(t1));
1177 < //         assertFalse(lock.hasQueuedThread(t2));
1178 < //         c.signal();
1179 < //         assertHasNoWaiters(lock, c);
1180 < //         assertTrue(lock.hasQueuedThread(t1));
1181 < //         assertTrue(lock.hasQueuedThread(t2));
1182 < //         writeLock.unlock();
1183 < //         awaitTermination(t1);
1184 < //         awaitTermination(t2);
1185 < //     }
1186 <
1187 < //     /**
1188 < //      * await after multiple reentrant locking preserves lock count
1189 < //      */
1190 < //     public void testAwaitLockCount()      { testAwaitLockCount(false); }
1191 < //     public void testAwaitLockCount_fair() { testAwaitLockCount(true); }
1192 < //     public void testAwaitLockCount(boolean fair) {
1193 < //         final PublicReentrantReadWriteLock lock =
1194 < //             new PublicReentrantReadWriteLock(fair);
1195 < //         final Condition c = lock.writeLock().newCondition();
1196 < //         final CountDownLatch locked = new CountDownLatch(2);
1197 < //         Thread t1 = newStartedThread(new CheckedRunnable() {
1198 < //             public void realRun() throws InterruptedException {
1199 < //                 lock.writeLock().lock();
1200 < //                 assertWriteLockedByMoi(lock);
1201 < //                 assertEquals(1, lock.writeLock().getHoldCount());
1202 < //                 locked.countDown();
1203 < //                 c.await();
1204 < //                 assertWriteLockedByMoi(lock);
1205 < //                 assertEquals(1, lock.writeLock().getHoldCount());
1206 < //                 lock.writeLock().unlock();
1207 < //             }});
1208 <
1209 < //         Thread t2 = newStartedThread(new CheckedRunnable() {
1210 < //             public void realRun() throws InterruptedException {
1211 < //                 lock.writeLock().lock();
1212 < //                 lock.writeLock().lock();
1213 < //                 assertWriteLockedByMoi(lock);
1214 < //                 assertEquals(2, lock.writeLock().getHoldCount());
1215 < //                 locked.countDown();
1216 < //                 c.await();
1217 < //                 assertWriteLockedByMoi(lock);
1218 < //                 assertEquals(2, lock.writeLock().getHoldCount());
1219 < //                 lock.writeLock().unlock();
1220 < //                 lock.writeLock().unlock();
1221 < //             }});
1222 <
1223 < //         await(locked);
1224 < //         lock.writeLock().lock();
1225 < //         assertHasWaiters(lock, c, t1, t2);
1226 < //         c.signalAll();
1227 < //         assertHasNoWaiters(lock, c);
1228 < //         lock.writeLock().unlock();
1229 < //         awaitTermination(t1);
1230 < //         awaitTermination(t2);
1231 < //     }
1232 <
1233 < //     /**
1234 < //      * A serialized lock deserializes as unlocked
1235 < //      */
1236 < //     public void testSerialization()      { testSerialization(false); }
1237 < //     public void testSerialization_fair() { testSerialization(true); }
1238 < //     public void testSerialization(boolean fair) {
1239 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1240 < //         lock.writeLock().lock();
1241 < //         lock.readLock().lock();
1242 <
1243 < //         ReentrantReadWriteLock clone = serialClone(lock);
1244 < //         assertEquals(lock.isFair(), clone.isFair());
1245 < //         assertTrue(lock.isWriteLocked());
1246 < //         assertFalse(clone.isWriteLocked());
1247 < //         assertEquals(1, lock.getReadLockCount());
1248 < //         assertEquals(0, clone.getReadLockCount());
1249 < //         clone.writeLock().lock();
1250 < //         clone.readLock().lock();
1251 < //         assertTrue(clone.isWriteLocked());
1252 < //         assertEquals(1, clone.getReadLockCount());
1253 < //         clone.readLock().unlock();
1254 < //         clone.writeLock().unlock();
1255 < //         assertFalse(clone.isWriteLocked());
1256 < //         assertEquals(1, lock.getReadLockCount());
1257 < //         assertEquals(0, clone.getReadLockCount());
1258 < //     }
1259 <
1260 < //     /**
1261 < //      * hasQueuedThreads reports whether there are waiting threads
1262 < //      */
1263 < //     public void testHasQueuedThreads()      { testHasQueuedThreads(false); }
1264 < //     public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
1265 < //     public void testHasQueuedThreads(boolean fair) {
1266 < //         final PublicReentrantReadWriteLock lock =
1267 < //             new PublicReentrantReadWriteLock(fair);
1268 < //         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1269 < //         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1270 < //         assertFalse(lock.hasQueuedThreads());
1271 < //         lock.writeLock().lock();
1272 < //         assertFalse(lock.hasQueuedThreads());
1273 < //         t1.start();
1274 < //         waitForQueuedThread(lock, t1);
1275 < //         assertTrue(lock.hasQueuedThreads());
1276 < //         t2.start();
1277 < //         waitForQueuedThread(lock, t2);
1278 < //         assertTrue(lock.hasQueuedThreads());
1279 < //         t1.interrupt();
1280 < //         awaitTermination(t1);
1281 < //         assertTrue(lock.hasQueuedThreads());
1282 < //         lock.writeLock().unlock();
1283 < //         awaitTermination(t2);
1284 < //         assertFalse(lock.hasQueuedThreads());
1285 < //     }
1286 <
1287 < //     /**
1288 < //      * hasQueuedThread(null) throws NPE
1289 < //      */
1290 < //     public void testHasQueuedThreadNPE()      { testHasQueuedThreadNPE(false); }
1291 < //     public void testHasQueuedThreadNPE_fair() { testHasQueuedThreadNPE(true); }
1292 < //     public void testHasQueuedThreadNPE(boolean fair) {
1293 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1294 < //         try {
1295 < //             lock.hasQueuedThread(null);
1296 < //             shouldThrow();
1297 < //         } catch (NullPointerException success) {}
1298 < //     }
1299 <
1300 < //     /**
1301 < //      * hasQueuedThread reports whether a thread is queued
1302 < //      */
1303 < //     public void testHasQueuedThread()      { testHasQueuedThread(false); }
1304 < //     public void testHasQueuedThread_fair() { testHasQueuedThread(true); }
1305 < //     public void testHasQueuedThread(boolean fair) {
1306 < //         final PublicReentrantReadWriteLock lock =
1307 < //             new PublicReentrantReadWriteLock(fair);
1308 < //         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1309 < //         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1310 < //         assertFalse(lock.hasQueuedThread(t1));
1311 < //         assertFalse(lock.hasQueuedThread(t2));
1312 < //         lock.writeLock().lock();
1313 < //         t1.start();
1314 < //         waitForQueuedThread(lock, t1);
1315 < //         assertTrue(lock.hasQueuedThread(t1));
1316 < //         assertFalse(lock.hasQueuedThread(t2));
1317 < //         t2.start();
1318 < //         waitForQueuedThread(lock, t2);
1319 < //         assertTrue(lock.hasQueuedThread(t1));
1320 < //         assertTrue(lock.hasQueuedThread(t2));
1321 < //         t1.interrupt();
1322 < //         awaitTermination(t1);
1323 < //         assertFalse(lock.hasQueuedThread(t1));
1324 < //         assertTrue(lock.hasQueuedThread(t2));
1325 < //         lock.writeLock().unlock();
1326 < //         awaitTermination(t2);
1327 < //         assertFalse(lock.hasQueuedThread(t1));
1328 < //         assertFalse(lock.hasQueuedThread(t2));
1329 < //     }
1330 <
1331 < //     /**
1332 < //      * getQueueLength reports number of waiting threads
1333 < //      */
1334 < //     public void testGetQueueLength()      { testGetQueueLength(false); }
1335 < //     public void testGetQueueLength_fair() { testGetQueueLength(true); }
1336 < //     public void testGetQueueLength(boolean fair) {
1337 < //         final PublicReentrantReadWriteLock lock =
1338 < //             new PublicReentrantReadWriteLock(fair);
1339 < //         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1340 < //         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1341 < //         assertEquals(0, lock.getQueueLength());
1342 < //         lock.writeLock().lock();
1343 < //         t1.start();
1344 < //         waitForQueuedThread(lock, t1);
1345 < //         assertEquals(1, lock.getQueueLength());
1346 < //         t2.start();
1347 < //         waitForQueuedThread(lock, t2);
1348 < //         assertEquals(2, lock.getQueueLength());
1349 < //         t1.interrupt();
1350 < //         awaitTermination(t1);
1351 < //         assertEquals(1, lock.getQueueLength());
1352 < //         lock.writeLock().unlock();
1353 < //         awaitTermination(t2);
1354 < //         assertEquals(0, lock.getQueueLength());
1355 < //     }
1356 <
1357 < //     /**
1358 < //      * getQueuedThreads includes waiting threads
1359 < //      */
1360 < //     public void testGetQueuedThreads()      { testGetQueuedThreads(false); }
1361 < //     public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
1362 < //     public void testGetQueuedThreads(boolean fair) {
1363 < //         final PublicReentrantReadWriteLock lock =
1364 < //             new PublicReentrantReadWriteLock(fair);
1365 < //         Thread t1 = new Thread(new InterruptedLockRunnable(lock));
1366 < //         Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
1367 < //         assertTrue(lock.getQueuedThreads().isEmpty());
1368 < //         lock.writeLock().lock();
1369 < //         assertTrue(lock.getQueuedThreads().isEmpty());
1370 < //         t1.start();
1371 < //         waitForQueuedThread(lock, t1);
1372 < //         assertEquals(1, lock.getQueuedThreads().size());
1373 < //         assertTrue(lock.getQueuedThreads().contains(t1));
1374 < //         t2.start();
1375 < //         waitForQueuedThread(lock, t2);
1376 < //         assertEquals(2, lock.getQueuedThreads().size());
1377 < //         assertTrue(lock.getQueuedThreads().contains(t1));
1378 < //         assertTrue(lock.getQueuedThreads().contains(t2));
1379 < //         t1.interrupt();
1380 < //         awaitTermination(t1);
1381 < //         assertFalse(lock.getQueuedThreads().contains(t1));
1382 < //         assertTrue(lock.getQueuedThreads().contains(t2));
1383 < //         assertEquals(1, lock.getQueuedThreads().size());
1384 < //         lock.writeLock().unlock();
1385 < //         awaitTermination(t2);
1386 < //         assertTrue(lock.getQueuedThreads().isEmpty());
1387 < //     }
1388 <
1389 < //     /**
1390 < //      * hasWaiters throws NPE if null
1391 < //      */
1392 < //     public void testHasWaitersNPE()      { testHasWaitersNPE(false); }
1393 < //     public void testHasWaitersNPE_fair() { testHasWaitersNPE(true); }
1394 < //     public void testHasWaitersNPE(boolean fair) {
1395 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1396 < //         try {
1397 < //             lock.hasWaiters(null);
1398 < //             shouldThrow();
1399 < //         } catch (NullPointerException success) {}
1400 < //     }
1401 <
1402 < //     /**
1403 < //      * getWaitQueueLength throws NPE if null
1404 < //      */
1405 < //     public void testGetWaitQueueLengthNPE()      { testGetWaitQueueLengthNPE(false); }
1406 < //     public void testGetWaitQueueLengthNPE_fair() { testGetWaitQueueLengthNPE(true); }
1407 < //     public void testGetWaitQueueLengthNPE(boolean fair) {
1408 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1409 < //         try {
1410 < //             lock.getWaitQueueLength(null);
1411 < //             shouldThrow();
1412 < //         } catch (NullPointerException success) {}
1413 < //     }
1414 <
1415 < //     /**
1416 < //      * getWaitingThreads throws NPE if null
1417 < //      */
1418 < //     public void testGetWaitingThreadsNPE()      { testGetWaitingThreadsNPE(false); }
1419 < //     public void testGetWaitingThreadsNPE_fair() { testGetWaitingThreadsNPE(true); }
1420 < //     public void testGetWaitingThreadsNPE(boolean fair) {
1421 < //         final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(fair);
1422 < //         try {
1423 < //             lock.getWaitingThreads(null);
1424 < //             shouldThrow();
1425 < //         } catch (NullPointerException success) {}
1426 < //     }
1427 <
1428 < //     /**
1429 < //      * hasWaiters throws IllegalArgumentException if not owned
1430 < //      */
1431 < //     public void testHasWaitersIAE()      { testHasWaitersIAE(false); }
1432 < //     public void testHasWaitersIAE_fair() { testHasWaitersIAE(true); }
1433 < //     public void testHasWaitersIAE(boolean fair) {
1434 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1435 < //         final Condition c = lock.writeLock().newCondition();
1436 < //         final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(fair);
1437 < //         try {
1438 < //             lock2.hasWaiters(c);
1439 < //             shouldThrow();
1440 < //         } catch (IllegalArgumentException success) {}
1441 < //     }
1442 <
1443 < //     /**
1444 < //      * hasWaiters throws IllegalMonitorStateException if not locked
1445 < //      */
1446 < //     public void testHasWaitersIMSE()      { testHasWaitersIMSE(false); }
1447 < //     public void testHasWaitersIMSE_fair() { testHasWaitersIMSE(true); }
1448 < //     public void testHasWaitersIMSE(boolean fair) {
1449 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1450 < //         final Condition c = lock.writeLock().newCondition();
1451 < //         try {
1452 < //             lock.hasWaiters(c);
1453 < //             shouldThrow();
1454 < //         } catch (IllegalMonitorStateException success) {}
1455 < //     }
1456 <
1457 < //     /**
1458 < //      * getWaitQueueLength throws IllegalArgumentException if not owned
1459 < //      */
1460 < //     public void testGetWaitQueueLengthIAE()      { testGetWaitQueueLengthIAE(false); }
1461 < //     public void testGetWaitQueueLengthIAE_fair() { testGetWaitQueueLengthIAE(true); }
1462 < //     public void testGetWaitQueueLengthIAE(boolean fair) {
1463 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1464 < //         final Condition c = lock.writeLock().newCondition();
1465 < //         final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(fair);
1466 < //         try {
1467 < //             lock2.getWaitQueueLength(c);
1468 < //             shouldThrow();
1469 < //         } catch (IllegalArgumentException success) {}
1470 < //     }
1471 <
1472 < //     /**
1473 < //      * getWaitQueueLength throws IllegalMonitorStateException if not locked
1474 < //      */
1475 < //     public void testGetWaitQueueLengthIMSE()      { testGetWaitQueueLengthIMSE(false); }
1476 < //     public void testGetWaitQueueLengthIMSE_fair() { testGetWaitQueueLengthIMSE(true); }
1477 < //     public void testGetWaitQueueLengthIMSE(boolean fair) {
1478 < //         final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1479 < //         final Condition c = lock.writeLock().newCondition();
1480 < //         try {
1481 < //             lock.getWaitQueueLength(c);
1482 < //             shouldThrow();
1483 < //         } catch (IllegalMonitorStateException success) {}
1484 < //     }
1485 <
1486 < //     /**
1487 < //      * getWaitingThreads throws IllegalArgumentException if not owned
1488 < //      */
1489 < //     public void testGetWaitingThreadsIAE()      { testGetWaitingThreadsIAE(false); }
1490 < //     public void testGetWaitingThreadsIAE_fair() { testGetWaitingThreadsIAE(true); }
1491 < //     public void testGetWaitingThreadsIAE(boolean fair) {
1492 < //         final PublicReentrantReadWriteLock lock =
1493 < //             new PublicReentrantReadWriteLock(fair);
1494 < //         final Condition c = lock.writeLock().newCondition();
1495 < //         final PublicReentrantReadWriteLock lock2 =
1496 < //             new PublicReentrantReadWriteLock(fair);
1497 < //         try {
1498 < //             lock2.getWaitingThreads(c);
1499 < //             shouldThrow();
1500 < //         } catch (IllegalArgumentException success) {}
1501 < //     }
1502 <
1503 < //     /**
1504 < //      * getWaitingThreads throws IllegalMonitorStateException if not locked
1505 < //      */
1506 < //     public void testGetWaitingThreadsIMSE()      { testGetWaitingThreadsIMSE(false); }
1507 < //     public void testGetWaitingThreadsIMSE_fair() { testGetWaitingThreadsIMSE(true); }
1508 < //     public void testGetWaitingThreadsIMSE(boolean fair) {
1509 < //         final PublicReentrantReadWriteLock lock =
1510 < //             new PublicReentrantReadWriteLock(fair);
1511 < //         final Condition c = lock.writeLock().newCondition();
1512 < //         try {
1513 < //             lock.getWaitingThreads(c);
1514 < //             shouldThrow();
1515 < //         } catch (IllegalMonitorStateException success) {}
1516 < //     }
1517 <
1518 < //     /**
1519 < //      * hasWaiters returns true when a thread is waiting, else false
1520 < //      */
1521 < //     public void testHasWaiters()      { testHasWaiters(false); }
1522 < //     public void testHasWaiters_fair() { testHasWaiters(true); }
1523 < //     public void testHasWaiters(boolean fair) {
1524 < //         final PublicReentrantReadWriteLock lock =
1525 < //             new PublicReentrantReadWriteLock(fair);
1526 < //         final Condition c = lock.writeLock().newCondition();
1527 < //         final CountDownLatch locked = new CountDownLatch(1);
1528 < //         Thread t = newStartedThread(new CheckedRunnable() {
1529 < //             public void realRun() throws InterruptedException {
1530 < //                 lock.writeLock().lock();
1531 < //                 assertHasNoWaiters(lock, c);
1532 < //                 assertFalse(lock.hasWaiters(c));
1533 < //                 locked.countDown();
1534 < //                 c.await();
1535 < //                 assertHasNoWaiters(lock, c);
1536 < //                 assertFalse(lock.hasWaiters(c));
1537 < //                 lock.writeLock().unlock();
1538 < //             }});
1539 <
1540 < //         await(locked);
1541 < //         lock.writeLock().lock();
1542 < //         assertHasWaiters(lock, c, t);
1543 < //         assertTrue(lock.hasWaiters(c));
1544 < //         c.signal();
1545 < //         assertHasNoWaiters(lock, c);
1546 < //         assertFalse(lock.hasWaiters(c));
1547 < //         lock.writeLock().unlock();
1548 < //         awaitTermination(t);
1549 < //         assertHasNoWaiters(lock, c);
1550 < //     }
1551 <
1552 < //     /**
1553 < //      * getWaitQueueLength returns number of waiting threads
1554 < //      */
1555 < //     public void testGetWaitQueueLength()      { testGetWaitQueueLength(false); }
1556 < //     public void testGetWaitQueueLength_fair() { testGetWaitQueueLength(true); }
1557 < //     public void testGetWaitQueueLength(boolean fair) {
1558 < //         final PublicReentrantReadWriteLock lock =
1559 < //             new PublicReentrantReadWriteLock(fair);
1560 < //         final Condition c = lock.writeLock().newCondition();
1561 < //         final CountDownLatch locked = new CountDownLatch(1);
1562 < //         Thread t = newStartedThread(new CheckedRunnable() {
1563 < //             public void realRun() throws InterruptedException {
1564 < //                 lock.writeLock().lock();
1565 < //                 assertEquals(0, lock.getWaitQueueLength(c));
1566 < //                 locked.countDown();
1567 < //                 c.await();
1568 < //                 lock.writeLock().unlock();
1569 < //             }});
1570 <
1571 < //         await(locked);
1572 < //         lock.writeLock().lock();
1573 < //         assertHasWaiters(lock, c, t);
1574 < //         assertEquals(1, lock.getWaitQueueLength(c));
1575 < //         c.signal();
1576 < //         assertHasNoWaiters(lock, c);
1577 < //         assertEquals(0, lock.getWaitQueueLength(c));
1578 < //         lock.writeLock().unlock();
1579 < //         awaitTermination(t);
1580 < //     }
1581 <
1582 < //     /**
1583 < //      * getWaitingThreads returns only and all waiting threads
1584 < //      */
1585 < //     public void testGetWaitingThreads()      { testGetWaitingThreads(false); }
1586 < //     public void testGetWaitingThreads_fair() { testGetWaitingThreads(true); }
1587 < //     public void testGetWaitingThreads(boolean fair) {
1588 < //         final PublicReentrantReadWriteLock lock =
1589 < //             new PublicReentrantReadWriteLock(fair);
1590 < //         final Condition c = lock.writeLock().newCondition();
1591 < //         final CountDownLatch locked1 = new CountDownLatch(1);
1592 < //         final CountDownLatch locked2 = new CountDownLatch(1);
1593 < //         Thread t1 = new Thread(new CheckedRunnable() {
1594 < //             public void realRun() throws InterruptedException {
1595 < //                 lock.writeLock().lock();
1596 < //                 assertTrue(lock.getWaitingThreads(c).isEmpty());
1597 < //                 locked1.countDown();
1598 < //                 c.await();
1599 < //                 lock.writeLock().unlock();
1600 < //             }});
1601 <
1602 < //         Thread t2 = new Thread(new CheckedRunnable() {
1603 < //             public void realRun() throws InterruptedException {
1604 < //                 lock.writeLock().lock();
1605 < //                 assertFalse(lock.getWaitingThreads(c).isEmpty());
1606 < //                 locked2.countDown();
1607 < //                 c.await();
1608 < //                 lock.writeLock().unlock();
1609 < //             }});
1610 <
1611 < //         lock.writeLock().lock();
1612 < //         assertTrue(lock.getWaitingThreads(c).isEmpty());
1613 < //         lock.writeLock().unlock();
1614 <
1615 < //         t1.start();
1616 < //         await(locked1);
1617 < //         t2.start();
1618 < //         await(locked2);
1619 <
1620 < //         lock.writeLock().lock();
1621 < //         assertTrue(lock.hasWaiters(c));
1622 < //         assertTrue(lock.getWaitingThreads(c).contains(t1));
1623 < //         assertTrue(lock.getWaitingThreads(c).contains(t2));
1624 < //         assertEquals(2, lock.getWaitingThreads(c).size());
1625 < //         c.signalAll();
1626 < //         assertHasNoWaiters(lock, c);
1627 < //         lock.writeLock().unlock();
1628 <
1629 < //         awaitTermination(t1);
1630 < //         awaitTermination(t2);
1631 <
1632 < //         assertHasNoWaiters(lock, c);
1633 < //     }
1634 <
1635 < //     /**
1636 < //      * toString indicates current lock state
1637 < //      */
1638 < //     public void testToString()      { testToString(false); }
1639 < //     public void testToString_fair() { testToString(true); }
1640 < //     public void testToString(boolean fair) {
1641 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1642 < //         assertTrue(lock.toString().contains("Write locks = 0"));
1643 < //         assertTrue(lock.toString().contains("Read locks = 0"));
1644 < //         lock.writeLock().lock();
1645 < //         assertTrue(lock.toString().contains("Write locks = 1"));
1646 < //         assertTrue(lock.toString().contains("Read locks = 0"));
1647 < //         lock.writeLock().unlock();
1648 < //         lock.readLock().lock();
1649 < //         lock.readLock().lock();
1650 < //         assertTrue(lock.toString().contains("Write locks = 0"));
1651 < //         assertTrue(lock.toString().contains("Read locks = 2"));
1652 < //     }
1653 <
1654 < //     /**
1655 < //      * readLock.toString indicates current lock state
1656 < //      */
1657 < //     public void testReadLockToString()      { testReadLockToString(false); }
1658 < //     public void testReadLockToString_fair() { testReadLockToString(true); }
1659 < //     public void testReadLockToString(boolean fair) {
1660 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1661 < //         assertTrue(lock.readLock().toString().contains("Read locks = 0"));
1662 < //         lock.readLock().lock();
1663 < //         lock.readLock().lock();
1664 < //         assertTrue(lock.readLock().toString().contains("Read locks = 2"));
1665 < //     }
1666 <
1667 < //     /**
1668 < //      * writeLock.toString indicates current lock state
1669 < //      */
1670 < //     public void testWriteLockToString()      { testWriteLockToString(false); }
1671 < //     public void testWriteLockToString_fair() { testWriteLockToString(true); }
1672 < //     public void testWriteLockToString(boolean fair) {
1673 < //         ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
1674 < //         assertTrue(lock.writeLock().toString().contains("Unlocked"));
1675 < //         lock.writeLock().lock();
1676 < //         assertTrue(lock.writeLock().toString().contains("Locked"));
1677 < //         lock.writeLock().unlock();
1678 < //         assertTrue(lock.writeLock().toString().contains("Unlocked"));
1679 < //     }
180 >    /**
181 >     * tryUnlockWrite fails if not write locked
182 >     */
183 >    public void testTryUnlockWrite_failure() {
184 >        StampedLock lock = new StampedLock();
185 >        assertFalse(lock.tryUnlockWrite());
186 >
187 >        for (Function<StampedLock, Long> readLocker : readLockers())
188 >        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
189 >            long s = assertValid(lock, readLocker.apply(lock));
190 >            assertFalse(lock.tryUnlockWrite());
191 >            assertTrue(lock.isReadLocked());
192 >            readUnlocker.accept(lock, s);
193 >            assertUnlocked(lock);
194 >        }
195 >    }
196  
197 +    /**
198 +     * tryUnlockRead fails if not read locked
199 +     */
200 +    public void testTryUnlockRead_failure() {
201 +        StampedLock lock = new StampedLock();
202 +        assertFalse(lock.tryUnlockRead());
203 +
204 +        for (Function<StampedLock, Long> writeLocker : writeLockers())
205 +        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
206 +            long s = writeLocker.apply(lock);
207 +            assertFalse(lock.tryUnlockRead());
208 +            assertTrue(lock.isWriteLocked());
209 +            writeUnlocker.accept(lock, s);
210 +            assertUnlocked(lock);
211 +        }
212 +    }
213 +
214 +    /**
215 +     * validate(0L) fails
216 +     */
217 +    public void testValidate0() {
218 +        StampedLock lock = new StampedLock();
219 +        assertFalse(lock.validate(0L));
220 +    }
221 +
222 +    /**
223 +     * A stamp obtained from a successful lock operation validates while the lock is held
224 +     */
225 +    public void testValidate() throws InterruptedException {
226 +        StampedLock lock = new StampedLock();
227 +
228 +        for (Function<StampedLock, Long> readLocker : readLockers())
229 +        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
230 +            long s = assertNonZero(readLocker.apply(lock));
231 +            assertTrue(lock.validate(s));
232 +            readUnlocker.accept(lock, s);
233 +        }
234 +
235 +        for (Function<StampedLock, Long> writeLocker : writeLockers())
236 +        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
237 +            long s = assertNonZero(writeLocker.apply(lock));
238 +            assertTrue(lock.validate(s));
239 +            writeUnlocker.accept(lock, s);
240 +        }
241 +    }
242 +
243 +    /**
244 +     * A stamp obtained from an unsuccessful lock operation does not validate
245 +     */
246 +    public void testValidate2() throws InterruptedException {
247 +        StampedLock lock = new StampedLock();
248 +        long s = assertNonZero(lock.writeLock());
249 +        assertTrue(lock.validate(s));
250 +        assertFalse(lock.validate(lock.tryWriteLock()));
251 +        assertFalse(lock.validate(lock.tryWriteLock(randomExpiredTimeout(),
252 +                                                    randomTimeUnit())));
253 +        assertFalse(lock.validate(lock.tryReadLock()));
254 +        assertFalse(lock.validate(lock.tryWriteLock(randomExpiredTimeout(),
255 +                                                    randomTimeUnit())));
256 +        assertFalse(lock.validate(lock.tryOptimisticRead()));
257 +        lock.unlockWrite(s);
258 +    }
259 +
260 +    void assertThrowInterruptedExceptionWhenPreInterrupted(Action[] actions) {
261 +        for (Action action : actions) {
262 +            Thread.currentThread().interrupt();
263 +            try {
264 +                action.run();
265 +                shouldThrow();
266 +            }
267 +            catch (InterruptedException success) {}
268 +            catch (Throwable fail) { threadUnexpectedException(fail); }
269 +            assertFalse(Thread.interrupted());
270 +        }
271 +    }
272 +
273 +    /**
274 +     * interruptible operations throw InterruptedException when pre-interrupted
275 +     */
276 +    public void testInterruptibleOperationsThrowInterruptedExceptionWhenPreInterrupted() {
277 +        final StampedLock lock = new StampedLock();
278 +
279 +        Action[] interruptibleLockActions = {
280 +            () -> lock.writeLockInterruptibly(),
281 +            () -> lock.tryWriteLock(Long.MIN_VALUE, DAYS),
282 +            () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
283 +            () -> lock.readLockInterruptibly(),
284 +            () -> lock.tryReadLock(Long.MIN_VALUE, DAYS),
285 +            () -> lock.tryReadLock(Long.MAX_VALUE, DAYS),
286 +            () -> lock.asWriteLock().lockInterruptibly(),
287 +            () -> lock.asWriteLock().tryLock(0L, DAYS),
288 +            () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
289 +            () -> lock.asReadLock().lockInterruptibly(),
290 +            () -> lock.asReadLock().tryLock(0L, DAYS),
291 +            () -> lock.asReadLock().tryLock(Long.MAX_VALUE, DAYS),
292 +        };
293 +        shuffle(interruptibleLockActions);
294 +
295 +        assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
296 +        {
297 +            long s = lock.writeLock();
298 +            assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
299 +            lock.unlockWrite(s);
300 +        }
301 +        {
302 +            long s = lock.readLock();
303 +            assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
304 +            lock.unlockRead(s);
305 +        }
306 +    }
307 +
308 +    void assertThrowInterruptedExceptionWhenInterrupted(Action[] actions) {
309 +        int n = actions.length;
310 +        Future<?>[] futures = new Future<?>[n];
311 +        CountDownLatch threadsStarted = new CountDownLatch(n);
312 +        CountDownLatch done = new CountDownLatch(n);
313 +
314 +        for (int i = 0; i < n; i++) {
315 +            Action action = actions[i];
316 +            futures[i] = cachedThreadPool.submit(new CheckedRunnable() {
317 +                public void realRun() throws Throwable {
318 +                    threadsStarted.countDown();
319 +                    try {
320 +                        action.run();
321 +                        shouldThrow();
322 +                    }
323 +                    catch (InterruptedException success) {}
324 +                    catch (Throwable fail) { threadUnexpectedException(fail); }
325 +                    assertFalse(Thread.interrupted());
326 +                    done.countDown();
327 +                }});
328 +        }
329 +
330 +        await(threadsStarted);
331 +        assertEquals(n, done.getCount());
332 +        for (Future<?> future : futures) // Interrupt all the tasks
333 +            future.cancel(true);
334 +        await(done);
335 +    }
336 +
337 +    /**
338 +     * interruptible operations throw InterruptedException when write locked and interrupted
339 +     */
340 +    public void testInterruptibleOperationsThrowInterruptedExceptionWriteLockedInterrupted() {
341 +        final StampedLock lock = new StampedLock();
342 +        long s = lock.writeLock();
343 +
344 +        Action[] interruptibleLockBlockingActions = {
345 +            () -> lock.writeLockInterruptibly(),
346 +            () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
347 +            () -> lock.readLockInterruptibly(),
348 +            () -> lock.tryReadLock(Long.MAX_VALUE, DAYS),
349 +            () -> lock.asWriteLock().lockInterruptibly(),
350 +            () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
351 +            () -> lock.asReadLock().lockInterruptibly(),
352 +            () -> lock.asReadLock().tryLock(Long.MAX_VALUE, DAYS),
353 +        };
354 +        shuffle(interruptibleLockBlockingActions);
355 +
356 +        assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions);
357 +    }
358 +
359 +    /**
360 +     * interruptible operations throw InterruptedException when read locked and interrupted
361 +     */
362 +    public void testInterruptibleOperationsThrowInterruptedExceptionReadLockedInterrupted() {
363 +        final StampedLock lock = new StampedLock();
364 +        long s = lock.readLock();
365 +
366 +        Action[] interruptibleLockBlockingActions = {
367 +            () -> lock.writeLockInterruptibly(),
368 +            () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
369 +            () -> lock.asWriteLock().lockInterruptibly(),
370 +            () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
371 +        };
372 +        shuffle(interruptibleLockBlockingActions);
373 +
374 +        assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions);
375 +    }
376 +
377 +    /**
378 +     * Non-interruptible operations ignore and preserve interrupt status
379 +     */
380 +    public void testNonInterruptibleOperationsIgnoreInterrupts() {
381 +        final StampedLock lock = new StampedLock();
382 +        Thread.currentThread().interrupt();
383 +
384 +        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
385 +            long s = assertValid(lock, lock.readLock());
386 +            readUnlocker.accept(lock, s);
387 +            s = assertValid(lock, lock.tryReadLock());
388 +            readUnlocker.accept(lock, s);
389 +        }
390 +
391 +        lock.asReadLock().lock();
392 +        lock.asReadLock().unlock();
393 +
394 +        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
395 +            long s = assertValid(lock, lock.writeLock());
396 +            writeUnlocker.accept(lock, s);
397 +            s = assertValid(lock, lock.tryWriteLock());
398 +            writeUnlocker.accept(lock, s);
399 +        }
400 +
401 +        lock.asWriteLock().lock();
402 +        lock.asWriteLock().unlock();
403 +
404 +        assertTrue(Thread.interrupted());
405 +    }
406 +
407 +    /**
408 +     * tryWriteLock on an unlocked lock succeeds
409 +     */
410 +    public void testTryWriteLock() {
411 +        final StampedLock lock = new StampedLock();
412 +        long s = lock.tryWriteLock();
413 +        assertTrue(s != 0L);
414 +        assertTrue(lock.isWriteLocked());
415 +        assertEquals(0L, lock.tryWriteLock());
416 +        releaseWriteLock(lock, s);
417 +    }
418 +
419 +    /**
420 +     * tryWriteLock fails if locked
421 +     */
422 +    public void testTryWriteLockWhenLocked() {
423 +        final StampedLock lock = new StampedLock();
424 +        long s = lock.writeLock();
425 +        Thread t = newStartedThread(new CheckedRunnable() {
426 +            public void realRun() {
427 +                assertEquals(0L, lock.tryWriteLock());
428 +            }});
429 +
430 +        assertEquals(0L, lock.tryWriteLock());
431 +        awaitTermination(t);
432 +        releaseWriteLock(lock, s);
433 +    }
434 +
435 +    /**
436 +     * tryReadLock fails if write-locked
437 +     */
438 +    public void testTryReadLockWhenLocked() {
439 +        final StampedLock lock = new StampedLock();
440 +        long s = lock.writeLock();
441 +        Thread t = newStartedThread(new CheckedRunnable() {
442 +            public void realRun() {
443 +                assertEquals(0L, lock.tryReadLock());
444 +            }});
445 +
446 +        assertEquals(0L, lock.tryReadLock());
447 +        awaitTermination(t);
448 +        releaseWriteLock(lock, s);
449 +    }
450 +
451 +    /**
452 +     * Multiple threads can hold a read lock when not write-locked
453 +     */
454 +    public void testMultipleReadLocks() {
455 +        final StampedLock lock = new StampedLock();
456 +        final long s = lock.readLock();
457 +        Thread t = newStartedThread(new CheckedRunnable() {
458 +            public void realRun() throws InterruptedException {
459 +                long s2 = lock.tryReadLock();
460 +                assertValid(lock, s2);
461 +                lock.unlockRead(s2);
462 +                long s3 = lock.tryReadLock(LONG_DELAY_MS, MILLISECONDS);
463 +                assertValid(lock, s3);
464 +                lock.unlockRead(s3);
465 +                long s4 = lock.readLock();
466 +                assertValid(lock, s4);
467 +                lock.unlockRead(s4);
468 +                lock.asReadLock().lock();
469 +                lock.asReadLock().unlock();
470 +                lock.asReadLock().lockInterruptibly();
471 +                lock.asReadLock().unlock();
472 +                lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS);
473 +                lock.asReadLock().unlock();
474 +            }});
475 +
476 +        awaitTermination(t);
477 +        lock.unlockRead(s);
478 +    }
479 +
480 +    /**
481 +     * writeLock() succeeds only after a reading thread unlocks
482 +     */
483 +    public void testWriteAfterReadLock() throws InterruptedException {
484 +        final CountDownLatch aboutToLock = new CountDownLatch(1);
485 +        final StampedLock lock = new StampedLock();
486 +        long rs = lock.readLock();
487 +        Thread t = newStartedThread(new CheckedRunnable() {
488 +            public void realRun() {
489 +                aboutToLock.countDown();
490 +                long s = lock.writeLock();
491 +                assertTrue(lock.isWriteLocked());
492 +                assertFalse(lock.isReadLocked());
493 +                lock.unlockWrite(s);
494 +            }});
495 +
496 +        await(aboutToLock);
497 +        assertThreadBlocks(t, Thread.State.WAITING);
498 +        assertFalse(lock.isWriteLocked());
499 +        assertTrue(lock.isReadLocked());
500 +        lock.unlockRead(rs);
501 +        awaitTermination(t);
502 +        assertUnlocked(lock);
503 +    }
504 +
505 +    /**
506 +     * writeLock() succeeds only after reading threads unlock
507 +     */
508 +    public void testWriteAfterMultipleReadLocks() {
509 +        final StampedLock lock = new StampedLock();
510 +        long s = lock.readLock();
511 +        Thread t1 = newStartedThread(new CheckedRunnable() {
512 +            public void realRun() {
513 +                long rs = lock.readLock();
514 +                lock.unlockRead(rs);
515 +            }});
516 +
517 +        awaitTermination(t1);
518 +
519 +        Thread t2 = newStartedThread(new CheckedRunnable() {
520 +            public void realRun() {
521 +                long ws = lock.writeLock();
522 +                lock.unlockWrite(ws);
523 +            }});
524 +
525 +        assertTrue(lock.isReadLocked());
526 +        assertFalse(lock.isWriteLocked());
527 +        lock.unlockRead(s);
528 +        awaitTermination(t2);
529 +        assertUnlocked(lock);
530 +    }
531 +
532 +    /**
533 +     * readLock() succeed only after a writing thread unlocks
534 +     */
535 +    public void testReadAfterWriteLock() {
536 +        final StampedLock lock = new StampedLock();
537 +        final CountDownLatch threadsStarted = new CountDownLatch(2);
538 +        final long s = lock.writeLock();
539 +        final Runnable acquireReleaseReadLock = new CheckedRunnable() {
540 +            public void realRun() {
541 +                threadsStarted.countDown();
542 +                long rs = lock.readLock();
543 +                assertTrue(lock.isReadLocked());
544 +                assertFalse(lock.isWriteLocked());
545 +                lock.unlockRead(rs);
546 +            }};
547 +        Thread t1 = newStartedThread(acquireReleaseReadLock);
548 +        Thread t2 = newStartedThread(acquireReleaseReadLock);
549 +
550 +        await(threadsStarted);
551 +        assertThreadBlocks(t1, Thread.State.WAITING);
552 +        assertThreadBlocks(t2, Thread.State.WAITING);
553 +        assertTrue(lock.isWriteLocked());
554 +        assertFalse(lock.isReadLocked());
555 +        releaseWriteLock(lock, s);
556 +        awaitTermination(t1);
557 +        awaitTermination(t2);
558 +        assertUnlocked(lock);
559 +    }
560 +
561 +    /**
562 +     * tryReadLock succeeds if read locked but not write locked
563 +     */
564 +    public void testTryLockWhenReadLocked() {
565 +        final StampedLock lock = new StampedLock();
566 +        long s = lock.readLock();
567 +        Thread t = newStartedThread(new CheckedRunnable() {
568 +            public void realRun() {
569 +                long rs = lock.tryReadLock();
570 +                assertValid(lock, rs);
571 +                lock.unlockRead(rs);
572 +            }});
573 +
574 +        awaitTermination(t);
575 +        lock.unlockRead(s);
576 +    }
577 +
578 +    /**
579 +     * tryWriteLock fails when read locked
580 +     */
581 +    public void testTryWriteLockWhenReadLocked() {
582 +        final StampedLock lock = new StampedLock();
583 +        long s = lock.readLock();
584 +        Thread t = newStartedThread(new CheckedRunnable() {
585 +            public void realRun() {
586 +                threadAssertEquals(0L, lock.tryWriteLock());
587 +            }});
588 +
589 +        awaitTermination(t);
590 +        lock.unlockRead(s);
591 +    }
592 +
593 +    /**
594 +     * timed lock operations time out if lock not available
595 +     */
596 +    public void testTimedLock_Timeout() throws Exception {
597 +        ArrayList<Future<?>> futures = new ArrayList<>();
598 +
599 +        // Write locked
600 +        final StampedLock lock = new StampedLock();
601 +        long stamp = lock.writeLock();
602 +        assertEquals(0L, lock.tryReadLock(0L, DAYS));
603 +        assertEquals(0L, lock.tryReadLock(Long.MIN_VALUE, DAYS));
604 +        assertFalse(lock.asReadLock().tryLock(0L, DAYS));
605 +        assertFalse(lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS));
606 +        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
607 +        assertEquals(0L, lock.tryWriteLock(Long.MIN_VALUE, DAYS));
608 +        assertFalse(lock.asWriteLock().tryLock(0L, DAYS));
609 +        assertFalse(lock.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
610 +
611 +        futures.add(cachedThreadPool.submit(new CheckedRunnable() {
612 +            public void realRun() throws InterruptedException {
613 +                long startTime = System.nanoTime();
614 +                assertEquals(0L, lock.tryWriteLock(timeoutMillis(), MILLISECONDS));
615 +                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
616 +            }}));
617 +
618 +        futures.add(cachedThreadPool.submit(new CheckedRunnable() {
619 +            public void realRun() throws InterruptedException {
620 +                long startTime = System.nanoTime();
621 +                assertEquals(0L, lock.tryReadLock(timeoutMillis(), MILLISECONDS));
622 +                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
623 +            }}));
624 +
625 +        // Read locked
626 +        final StampedLock lock2 = new StampedLock();
627 +        long stamp2 = lock2.readLock();
628 +        assertEquals(0L, lock2.tryWriteLock(0L, DAYS));
629 +        assertEquals(0L, lock2.tryWriteLock(Long.MIN_VALUE, DAYS));
630 +        assertFalse(lock2.asWriteLock().tryLock(0L, DAYS));
631 +        assertFalse(lock2.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
632 +
633 +        futures.add(cachedThreadPool.submit(new CheckedRunnable() {
634 +            public void realRun() throws InterruptedException {
635 +                long startTime = System.nanoTime();
636 +                assertEquals(0L, lock2.tryWriteLock(timeoutMillis(), MILLISECONDS));
637 +                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
638 +            }}));
639 +
640 +        for (Future<?> future : futures)
641 +            assertNull(future.get());
642 +
643 +        releaseWriteLock(lock, stamp);
644 +        releaseReadLock(lock2, stamp2);
645 +    }
646 +
647 +    /**
648 +     * writeLockInterruptibly succeeds if unlocked
649 +     */
650 +    public void testWriteLockInterruptibly() throws InterruptedException {
651 +        final StampedLock lock = new StampedLock();
652 +        long s = lock.writeLockInterruptibly();
653 +        assertTrue(lock.isWriteLocked());
654 +        releaseWriteLock(lock, s);
655 +    }
656 +
657 +    /**
658 +     * readLockInterruptibly succeeds if lock free
659 +     */
660 +    public void testReadLockInterruptibly() throws InterruptedException {
661 +        final StampedLock lock = new StampedLock();
662 +
663 +        long s = assertValid(lock, lock.readLockInterruptibly());
664 +        assertTrue(lock.isReadLocked());
665 +        lock.unlockRead(s);
666 +
667 +        lock.asReadLock().lockInterruptibly();
668 +        assertTrue(lock.isReadLocked());
669 +        lock.asReadLock().unlock();
670 +    }
671 +
672 +    /**
673 +     * A serialized lock deserializes as unlocked
674 +     */
675 +    public void testSerialization() {
676 +        StampedLock lock = new StampedLock();
677 +        lock.writeLock();
678 +        StampedLock clone = serialClone(lock);
679 +        assertTrue(lock.isWriteLocked());
680 +        assertFalse(clone.isWriteLocked());
681 +        long s = clone.writeLock();
682 +        assertTrue(clone.isWriteLocked());
683 +        clone.unlockWrite(s);
684 +        assertFalse(clone.isWriteLocked());
685 +    }
686 +
687 +    /**
688 +     * toString indicates current lock state
689 +     */
690 +    public void testToString() {
691 +        StampedLock lock = new StampedLock();
692 +        assertTrue(lock.toString().contains("Unlocked"));
693 +        long s = lock.writeLock();
694 +        assertTrue(lock.toString().contains("Write-locked"));
695 +        lock.unlockWrite(s);
696 +        s = lock.readLock();
697 +        assertTrue(lock.toString().contains("Read-locks"));
698 +    }
699 +
700 +    /**
701 +     * tryOptimisticRead succeeds and validates if unlocked, fails if
702 +     * exclusively locked
703 +     */
704 +    public void testValidateOptimistic() throws InterruptedException {
705 +        StampedLock lock = new StampedLock();
706 +
707 +        assertValid(lock, lock.tryOptimisticRead());
708 +
709 +        for (Function<StampedLock, Long> writeLocker : writeLockers()) {
710 +            long s = assertValid(lock, writeLocker.apply(lock));
711 +            assertEquals(0L, lock.tryOptimisticRead());
712 +            releaseWriteLock(lock, s);
713 +        }
714 +
715 +        for (Function<StampedLock, Long> readLocker : readLockers()) {
716 +            long s = assertValid(lock, readLocker.apply(lock));
717 +            long p = assertValid(lock, lock.tryOptimisticRead());
718 +            releaseReadLock(lock, s);
719 +            assertTrue(lock.validate(p));
720 +        }
721 +
722 +        assertValid(lock, lock.tryOptimisticRead());
723 +    }
724 +
725 +    /**
726 +     * tryOptimisticRead stamp does not validate if a write lock intervenes
727 +     */
728 +    public void testValidateOptimisticWriteLocked() {
729 +        final StampedLock lock = new StampedLock();
730 +        final long p = assertValid(lock, lock.tryOptimisticRead());
731 +        final long s = assertValid(lock, lock.writeLock());
732 +        assertFalse(lock.validate(p));
733 +        assertEquals(0L, lock.tryOptimisticRead());
734 +        assertTrue(lock.validate(s));
735 +        lock.unlockWrite(s);
736 +    }
737 +
738 +    /**
739 +     * tryOptimisticRead stamp does not validate if a write lock
740 +     * intervenes in another thread
741 +     */
742 +    public void testValidateOptimisticWriteLocked2()
743 +            throws InterruptedException {
744 +        final CountDownLatch locked = new CountDownLatch(1);
745 +        final StampedLock lock = new StampedLock();
746 +        final long p = assertValid(lock, lock.tryOptimisticRead());
747 +
748 +        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
749 +            public void realRun() throws InterruptedException {
750 +                lock.writeLockInterruptibly();
751 +                locked.countDown();
752 +                lock.writeLockInterruptibly();
753 +            }});
754 +
755 +        await(locked);
756 +        assertFalse(lock.validate(p));
757 +        assertEquals(0L, lock.tryOptimisticRead());
758 +        assertThreadBlocks(t, Thread.State.WAITING);
759 +        t.interrupt();
760 +        awaitTermination(t);
761 +        assertTrue(lock.isWriteLocked());
762 +    }
763 +
764 +    /**
765 +     * tryConvertToOptimisticRead succeeds and validates if successfully locked
766 +     */
767 +    public void testTryConvertToOptimisticRead() throws InterruptedException {
768 +        StampedLock lock = new StampedLock();
769 +        long s, p, q;
770 +        assertEquals(0L, lock.tryConvertToOptimisticRead(0L));
771 +
772 +        s = assertValid(lock, lock.tryOptimisticRead());
773 +        assertEquals(s, lock.tryConvertToOptimisticRead(s));
774 +        assertTrue(lock.validate(s));
775 +
776 +        for (Function<StampedLock, Long> writeLocker : writeLockers()) {
777 +            s = assertValid(lock, writeLocker.apply(lock));
778 +            p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
779 +            assertFalse(lock.validate(s));
780 +            assertTrue(lock.validate(p));
781 +            assertUnlocked(lock);
782 +        }
783 +
784 +        for (Function<StampedLock, Long> readLocker : readLockers()) {
785 +            s = assertValid(lock, readLocker.apply(lock));
786 +            q = assertValid(lock, lock.tryOptimisticRead());
787 +            assertEquals(q, lock.tryConvertToOptimisticRead(q));
788 +            assertTrue(lock.validate(q));
789 +            assertTrue(lock.isReadLocked());
790 +            p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
791 +            assertTrue(lock.validate(p));
792 +            assertTrue(lock.validate(s));
793 +            assertUnlocked(lock);
794 +            assertEquals(q, lock.tryConvertToOptimisticRead(q));
795 +            assertTrue(lock.validate(q));
796 +        }
797 +    }
798 +
799 +    /**
800 +     * tryConvertToReadLock succeeds for valid stamps
801 +     */
802 +    public void testTryConvertToReadLock() throws InterruptedException {
803 +        StampedLock lock = new StampedLock();
804 +        long s, p;
805 +
806 +        assertEquals(0L, lock.tryConvertToReadLock(0L));
807 +
808 +        s = assertValid(lock, lock.tryOptimisticRead());
809 +        p = assertValid(lock, lock.tryConvertToReadLock(s));
810 +        assertTrue(lock.isReadLocked());
811 +        assertEquals(1, lock.getReadLockCount());
812 +        assertTrue(lock.validate(s));
813 +        lock.unlockRead(p);
814 +
815 +        s = assertValid(lock, lock.tryOptimisticRead());
816 +        lock.readLock();
817 +        p = assertValid(lock, lock.tryConvertToReadLock(s));
818 +        assertTrue(lock.isReadLocked());
819 +        assertEquals(2, lock.getReadLockCount());
820 +        lock.unlockRead(p);
821 +        lock.unlockRead(p);
822 +        assertUnlocked(lock);
823 +
824 +        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
825 +            for (Function<StampedLock, Long> writeLocker : writeLockers()) {
826 +                s = assertValid(lock, writeLocker.apply(lock));
827 +                p = assertValid(lock, lock.tryConvertToReadLock(s));
828 +                assertFalse(lock.validate(s));
829 +                assertTrue(lock.isReadLocked());
830 +                assertEquals(1, lock.getReadLockCount());
831 +                readUnlocker.accept(lock, p);
832 +            }
833 +
834 +            for (Function<StampedLock, Long> readLocker : readLockers()) {
835 +                s = assertValid(lock, readLocker.apply(lock));
836 +                assertEquals(s, lock.tryConvertToReadLock(s));
837 +                assertTrue(lock.validate(s));
838 +                assertTrue(lock.isReadLocked());
839 +                assertEquals(1, lock.getReadLockCount());
840 +                readUnlocker.accept(lock, s);
841 +            }
842 +        }
843 +    }
844 +
845 +    /**
846 +     * tryConvertToWriteLock succeeds if lock available; fails if multiply read locked
847 +     */
848 +    public void testTryConvertToWriteLock() throws InterruptedException {
849 +        StampedLock lock = new StampedLock();
850 +        long s, p;
851 +
852 +        assertEquals(0L, lock.tryConvertToWriteLock(0L));
853 +
854 +        assertTrue((s = lock.tryOptimisticRead()) != 0L);
855 +        assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
856 +        assertTrue(lock.isWriteLocked());
857 +        lock.unlockWrite(p);
858 +
859 +        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
860 +            for (Function<StampedLock, Long> writeLocker : writeLockers()) {
861 +                s = assertValid(lock, writeLocker.apply(lock));
862 +                assertEquals(s, lock.tryConvertToWriteLock(s));
863 +                assertTrue(lock.validate(s));
864 +                assertTrue(lock.isWriteLocked());
865 +                writeUnlocker.accept(lock, s);
866 +            }
867 +
868 +            for (Function<StampedLock, Long> readLocker : readLockers()) {
869 +                s = assertValid(lock, readLocker.apply(lock));
870 +                p = assertValid(lock, lock.tryConvertToWriteLock(s));
871 +                assertFalse(lock.validate(s));
872 +                assertTrue(lock.validate(p));
873 +                assertTrue(lock.isWriteLocked());
874 +                writeUnlocker.accept(lock, p);
875 +            }
876 +        }
877 +
878 +        // failure if multiply read locked
879 +        for (Function<StampedLock, Long> readLocker : readLockers()) {
880 +            s = assertValid(lock, readLocker.apply(lock));
881 +            p = assertValid(lock, readLocker.apply(lock));
882 +            assertEquals(0L, lock.tryConvertToWriteLock(s));
883 +            assertTrue(lock.validate(s));
884 +            assertTrue(lock.validate(p));
885 +            assertEquals(2, lock.getReadLockCount());
886 +            lock.unlock(p);
887 +            lock.unlock(s);
888 +            assertUnlocked(lock);
889 +        }
890 +    }
891 +
892 +    /**
893 +     * asWriteLock can be locked and unlocked
894 +     */
895 +    public void testAsWriteLock() throws Throwable {
896 +        StampedLock sl = new StampedLock();
897 +        Lock lock = sl.asWriteLock();
898 +        for (Action locker : lockLockers(lock)) {
899 +            locker.run();
900 +            assertTrue(sl.isWriteLocked());
901 +            assertFalse(sl.isReadLocked());
902 +            assertFalse(lock.tryLock());
903 +            lock.unlock();
904 +            assertUnlocked(sl);
905 +        }
906 +    }
907 +
908 +    /**
909 +     * asReadLock can be locked and unlocked
910 +     */
911 +    public void testAsReadLock() throws Throwable {
912 +        StampedLock sl = new StampedLock();
913 +        Lock lock = sl.asReadLock();
914 +        for (Action locker : lockLockers(lock)) {
915 +            locker.run();
916 +            assertTrue(sl.isReadLocked());
917 +            assertFalse(sl.isWriteLocked());
918 +            assertEquals(1, sl.getReadLockCount());
919 +            locker.run();
920 +            assertTrue(sl.isReadLocked());
921 +            assertEquals(2, sl.getReadLockCount());
922 +            lock.unlock();
923 +            lock.unlock();
924 +            assertUnlocked(sl);
925 +        }
926 +    }
927 +
928 +    /**
929 +     * asReadWriteLock.writeLock can be locked and unlocked
930 +     */
931 +    public void testAsReadWriteLockWriteLock() throws Throwable {
932 +        StampedLock sl = new StampedLock();
933 +        Lock lock = sl.asReadWriteLock().writeLock();
934 +        for (Action locker : lockLockers(lock)) {
935 +            locker.run();
936 +            assertTrue(sl.isWriteLocked());
937 +            assertFalse(sl.isReadLocked());
938 +            assertFalse(lock.tryLock());
939 +            lock.unlock();
940 +            assertUnlocked(sl);
941 +        }
942 +    }
943 +
944 +    /**
945 +     * asReadWriteLock.readLock can be locked and unlocked
946 +     */
947 +    public void testAsReadWriteLockReadLock() throws Throwable {
948 +        StampedLock sl = new StampedLock();
949 +        Lock lock = sl.asReadWriteLock().readLock();
950 +        for (Action locker : lockLockers(lock)) {
951 +            locker.run();
952 +            assertTrue(sl.isReadLocked());
953 +            assertFalse(sl.isWriteLocked());
954 +            assertEquals(1, sl.getReadLockCount());
955 +            locker.run();
956 +            assertTrue(sl.isReadLocked());
957 +            assertEquals(2, sl.getReadLockCount());
958 +            lock.unlock();
959 +            lock.unlock();
960 +            assertUnlocked(sl);
961 +        }
962 +    }
963 +
964 +    /**
965 +     * Lock.newCondition throws UnsupportedOperationException
966 +     */
967 +    public void testLockViewsDoNotSupportConditions() {
968 +        StampedLock sl = new StampedLock();
969 +        assertThrows(UnsupportedOperationException.class,
970 +                     () -> sl.asWriteLock().newCondition(),
971 +                     () -> sl.asReadLock().newCondition(),
972 +                     () -> sl.asReadWriteLock().writeLock().newCondition(),
973 +                     () -> sl.asReadWriteLock().readLock().newCondition());
974 +    }
975 +
976 +    /**
977 +     * Passing optimistic read stamps to unlock operations result in
978 +     * IllegalMonitorStateException
979 +     */
980 +    public void testCannotUnlockOptimisticReadStamps() {
981 +        Runnable[] actions = {
982 +            () -> {
983 +                StampedLock sl = new StampedLock();
984 +                long stamp = assertValid(sl, sl.tryOptimisticRead());
985 +                sl.unlockRead(stamp);
986 +            },
987 +            () -> {
988 +                StampedLock sl = new StampedLock();
989 +                long stamp = sl.tryOptimisticRead();
990 +                sl.unlock(stamp);
991 +            },
992 +
993 +            () -> {
994 +                StampedLock sl = new StampedLock();
995 +                long stamp = sl.tryOptimisticRead();
996 +                sl.writeLock();
997 +                sl.unlock(stamp);
998 +            },
999 +            () -> {
1000 +                StampedLock sl = new StampedLock();
1001 +                sl.readLock();
1002 +                long stamp = assertValid(sl, sl.tryOptimisticRead());
1003 +                sl.unlockRead(stamp);
1004 +            },
1005 +            () -> {
1006 +                StampedLock sl = new StampedLock();
1007 +                sl.readLock();
1008 +                long stamp = assertValid(sl, sl.tryOptimisticRead());
1009 +                sl.unlock(stamp);
1010 +            },
1011 +
1012 +            () -> {
1013 +                StampedLock sl = new StampedLock();
1014 +                long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1015 +                assertValid(sl, stamp);
1016 +                sl.writeLock();
1017 +                sl.unlockWrite(stamp);
1018 +            },
1019 +            () -> {
1020 +                StampedLock sl = new StampedLock();
1021 +                long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1022 +                sl.writeLock();
1023 +                sl.unlock(stamp);
1024 +            },
1025 +            () -> {
1026 +                StampedLock sl = new StampedLock();
1027 +                long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1028 +                sl.readLock();
1029 +                sl.unlockRead(stamp);
1030 +            },
1031 +            () -> {
1032 +                StampedLock sl = new StampedLock();
1033 +                long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
1034 +                sl.readLock();
1035 +                sl.unlock(stamp);
1036 +            },
1037 +
1038 +            () -> {
1039 +                StampedLock sl = new StampedLock();
1040 +                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1041 +                assertValid(sl, stamp);
1042 +                sl.writeLock();
1043 +                sl.unlockWrite(stamp);
1044 +            },
1045 +            () -> {
1046 +                StampedLock sl = new StampedLock();
1047 +                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1048 +                sl.writeLock();
1049 +                sl.unlock(stamp);
1050 +            },
1051 +            () -> {
1052 +                StampedLock sl = new StampedLock();
1053 +                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1054 +                sl.readLock();
1055 +                sl.unlockRead(stamp);
1056 +            },
1057 +            () -> {
1058 +                StampedLock sl = new StampedLock();
1059 +                sl.readLock();
1060 +                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1061 +                assertValid(sl, stamp);
1062 +                sl.readLock();
1063 +                sl.unlockRead(stamp);
1064 +            },
1065 +            () -> {
1066 +                StampedLock sl = new StampedLock();
1067 +                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1068 +                sl.readLock();
1069 +                sl.unlock(stamp);
1070 +            },
1071 +            () -> {
1072 +                StampedLock sl = new StampedLock();
1073 +                sl.readLock();
1074 +                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
1075 +                sl.readLock();
1076 +                sl.unlock(stamp);
1077 +            },
1078 +        };
1079 +
1080 +        assertThrows(IllegalMonitorStateException.class, actions);
1081 +    }
1082 +
1083 +    static long writeLockInterruptiblyUninterrupted(StampedLock sl) {
1084 +        try { return sl.writeLockInterruptibly(); }
1085 +        catch (InterruptedException ex) { throw new AssertionError(ex); }
1086 +    }
1087 +
1088 +    static long tryWriteLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1089 +        try { return sl.tryWriteLock(time, unit); }
1090 +        catch (InterruptedException ex) { throw new AssertionError(ex); }
1091 +    }
1092 +
1093 +    static long readLockInterruptiblyUninterrupted(StampedLock sl) {
1094 +        try { return sl.readLockInterruptibly(); }
1095 +        catch (InterruptedException ex) { throw new AssertionError(ex); }
1096 +    }
1097 +
1098 +    static long tryReadLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
1099 +        try { return sl.tryReadLock(time, unit); }
1100 +        catch (InterruptedException ex) { throw new AssertionError(ex); }
1101 +    }
1102 +
1103 +    /**
1104 +     * Invalid stamps result in IllegalMonitorStateException
1105 +     */
1106 +    public void testInvalidStampsThrowIllegalMonitorStateException() {
1107 +        final StampedLock sl = new StampedLock();
1108 +
1109 +        assertThrows(IllegalMonitorStateException.class,
1110 +                     () -> sl.unlockWrite(0L),
1111 +                     () -> sl.unlockRead(0L),
1112 +                     () -> sl.unlock(0L));
1113 +
1114 +        final long optimisticStamp = sl.tryOptimisticRead();
1115 +        final long readStamp = sl.readLock();
1116 +        sl.unlockRead(readStamp);
1117 +        final long writeStamp = sl.writeLock();
1118 +        sl.unlockWrite(writeStamp);
1119 +        assertTrue(optimisticStamp != 0L && readStamp != 0L && writeStamp != 0L);
1120 +        final long[] noLongerValidStamps = { optimisticStamp, readStamp, writeStamp };
1121 +        final Runnable assertNoLongerValidStampsThrow = () -> {
1122 +            for (long noLongerValidStamp : noLongerValidStamps)
1123 +                assertThrows(IllegalMonitorStateException.class,
1124 +                             () -> sl.unlockWrite(noLongerValidStamp),
1125 +                             () -> sl.unlockRead(noLongerValidStamp),
1126 +                             () -> sl.unlock(noLongerValidStamp));
1127 +        };
1128 +        assertNoLongerValidStampsThrow.run();
1129 +
1130 +        for (Function<StampedLock, Long> readLocker : readLockers())
1131 +        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
1132 +            final long stamp = readLocker.apply(sl);
1133 +            assertValid(sl, stamp);
1134 +            assertNoLongerValidStampsThrow.run();
1135 +            assertThrows(IllegalMonitorStateException.class,
1136 +                         () -> sl.unlockWrite(stamp),
1137 +                         () -> sl.unlockRead(sl.tryOptimisticRead()),
1138 +                         () -> sl.unlockRead(0L));
1139 +            readUnlocker.accept(sl, stamp);
1140 +            assertUnlocked(sl);
1141 +            assertNoLongerValidStampsThrow.run();
1142 +        }
1143 +
1144 +        for (Function<StampedLock, Long> writeLocker : writeLockers())
1145 +        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
1146 +            final long stamp = writeLocker.apply(sl);
1147 +            assertValid(sl, stamp);
1148 +            assertNoLongerValidStampsThrow.run();
1149 +            assertThrows(IllegalMonitorStateException.class,
1150 +                         () -> sl.unlockRead(stamp),
1151 +                         () -> sl.unlockWrite(0L));
1152 +            writeUnlocker.accept(sl, stamp);
1153 +            assertUnlocked(sl);
1154 +            assertNoLongerValidStampsThrow.run();
1155 +        }
1156 +    }
1157 +
1158 +    /**
1159 +     * Read locks can be very deeply nested
1160 +     */
1161 +    public void testDeeplyNestedReadLocks() {
1162 +        final StampedLock lock = new StampedLock();
1163 +        final int depth = 300;
1164 +        final long[] stamps = new long[depth];
1165 +        final List<Function<StampedLock, Long>> readLockers = readLockers();
1166 +        final List<BiConsumer<StampedLock, Long>> readUnlockers = readUnlockers();
1167 +        for (int i = 0; i < depth; i++) {
1168 +            Function<StampedLock, Long> readLocker
1169 +                = readLockers.get(i % readLockers.size());
1170 +            long stamp = readLocker.apply(lock);
1171 +            assertEquals(i + 1, lock.getReadLockCount());
1172 +            assertTrue(lock.isReadLocked());
1173 +            stamps[i] = stamp;
1174 +        }
1175 +        for (int i = 0; i < depth; i++) {
1176 +            BiConsumer<StampedLock, Long> readUnlocker
1177 +                = readUnlockers.get(i % readUnlockers.size());
1178 +            assertEquals(depth - i, lock.getReadLockCount());
1179 +            assertTrue(lock.isReadLocked());
1180 +            readUnlocker.accept(lock, stamps[depth - 1 - i]);
1181 +        }
1182 +        assertUnlocked(lock);
1183 +    }
1184   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines