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

Comparing jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java (file contents):
Revision 1.12 by dl, Fri Jan 9 14:45:58 2004 UTC vs.
Revision 1.45 by jsr166, Tue Dec 2 07:23:13 2014 UTC

# Line 1 | Line 1
1   /*
2   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at
4 < * http://creativecommons.org/licenses/publicdomain
5 < * Other contributors include Andrew Wright, Jeffrey Hayes,
6 < * Pat Fisher, Mike Judd.
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5 > * Other contributors include Andrew Wright, Jeffrey Hayes,
6 > * Pat Fisher, Mike Judd.
7   */
8  
9
9   import junit.framework.*;
10   import java.util.*;
11 < import java.util.concurrent.*;
12 < import java.util.concurrent.locks.*;
13 < import java.io.*;
11 > import static java.util.concurrent.TimeUnit.MILLISECONDS;
12 > import static java.util.concurrent.TimeUnit.NANOSECONDS;
13 > import java.util.concurrent.locks.AbstractQueuedSynchronizer;
14 > import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject;
15  
16   public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
17      public static void main(String[] args) {
18 <        junit.textui.TestRunner.run (suite());
18 >        junit.textui.TestRunner.run(suite());
19      }
20      public static Test suite() {
21          return new TestSuite(AbstractQueuedSynchronizerTest.class);
22      }
23  
24      /**
25 <     * A simple mutex class, adapted from the
26 <     * AbstractQueuedSynchronizer javadoc.  Exclusive acquire tests
27 <     * exercise this as a sample user extension.  Other
28 <     * methods/features of AbstractQueuedSynchronizerTest are tested
29 <     * via other test classes, including those for ReentrantLock,
30 <     * ReentrantReadWriteLock, and Semaphore
25 >     * A simple mutex class, adapted from the class javadoc.  Exclusive
26 >     * acquire tests exercise this as a sample user extension.  Other
27 >     * methods/features of AbstractQueuedSynchronizer are tested via
28 >     * other test classes, including those for ReentrantLock,
29 >     * ReentrantReadWriteLock, and Semaphore.
30       */
31      static class Mutex extends AbstractQueuedSynchronizer {
32 <        public boolean isLocked() { return getState() == 1; }
33 <        
34 <        public boolean tryAcquireExclusive(int acquires) {
35 <            assertTrue(acquires == 1);
36 <            return compareAndSetState(0, 1);
37 <        }
38 <        
39 <        public boolean tryReleaseExclusive(int releases) {
40 <            setState(0);
32 >        /** An eccentric value for locked synchronizer state. */
33 >        static final int LOCKED = (1 << 31) | (1 << 15);
34 >
35 >        static final int UNLOCKED = 0;
36 >
37 >        @Override public boolean isHeldExclusively() {
38 >            int state = getState();
39 >            assertTrue(state == UNLOCKED || state == LOCKED);
40 >            return state == LOCKED;
41 >        }
42 >
43 >        @Override public boolean tryAcquire(int acquires) {
44 >            assertEquals(LOCKED, acquires);
45 >            return compareAndSetState(UNLOCKED, LOCKED);
46 >        }
47 >
48 >        @Override public boolean tryRelease(int releases) {
49 >            if (getState() != LOCKED) throw new IllegalMonitorStateException();
50 >            assertEquals(LOCKED, releases);
51 >            setState(UNLOCKED);
52              return true;
53          }
54 <        
55 <        public void checkConditionAccess(Thread thread) {
56 <            if (getState() == 0) throw new IllegalMonitorStateException();
54 >
55 >        public boolean tryAcquireNanos(long nanos) throws InterruptedException {
56 >            return tryAcquireNanos(LOCKED, nanos);
57 >        }
58 >
59 >        public boolean tryAcquire() {
60 >            return tryAcquire(LOCKED);
61 >        }
62 >
63 >        public boolean tryRelease() {
64 >            return tryRelease(LOCKED);
65 >        }
66 >
67 >        public void acquire() {
68 >            acquire(LOCKED);
69          }
70 <        
71 <        public ConditionObject newCondition() { return new ConditionObject(); }
72 <        
73 <        public void lock() {
74 <            acquireExclusiveUninterruptibly(1);
70 >
71 >        public void acquireInterruptibly() throws InterruptedException {
72 >            acquireInterruptibly(LOCKED);
73 >        }
74 >
75 >        public void release() {
76 >            release(LOCKED);
77          }
78  
79 +        public ConditionObject newCondition() {
80 +            return new ConditionObject();
81 +        }
82      }
83  
57    
84      /**
85       * A simple latch class, to test shared mode.
86       */
87 <    static class BooleanLatch extends AbstractQueuedSynchronizer {
87 >    static class BooleanLatch extends AbstractQueuedSynchronizer {
88          public boolean isSignalled() { return getState() != 0; }
89  
90          public int tryAcquireShared(int ignore) {
91 <            return isSignalled()? 1 : -1;
91 >            return isSignalled() ? 1 : -1;
92          }
93 <        
93 >
94          public boolean tryReleaseShared(int ignore) {
95              setState(1);
96              return true;
# Line 72 | Line 98 | public class AbstractQueuedSynchronizerT
98      }
99  
100      /**
101 <     * A runnable calling acquireExclusiveInterruptibly
101 >     * A runnable calling acquireInterruptibly that does not expect to
102 >     * be interrupted.
103       */
104 <    class InterruptibleLockRunnable implements Runnable {
105 <        final Mutex lock;
106 <        InterruptibleLockRunnable(Mutex l) { lock = l; }
107 <        public void run() {
108 <            try {
109 <                lock.acquireExclusiveInterruptibly(1);
110 <            } catch(InterruptedException success){}
104 >    class InterruptibleSyncRunnable extends CheckedRunnable {
105 >        final Mutex sync;
106 >        InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; }
107 >        public void realRun() throws InterruptedException {
108 >            sync.acquireInterruptibly();
109 >        }
110 >    }
111 >
112 >    /**
113 >     * A runnable calling acquireInterruptibly that expects to be
114 >     * interrupted.
115 >     */
116 >    class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
117 >        final Mutex sync;
118 >        InterruptedSyncRunnable(Mutex sync) { this.sync = sync; }
119 >        public void realRun() throws InterruptedException {
120 >            sync.acquireInterruptibly();
121          }
122      }
123  
124 +    /** A constant to clarify calls to checking methods below. */
125 +    static final Thread[] NO_THREADS = new Thread[0];
126  
127      /**
128 <     * A runnable calling acquireExclusiveInterruptibly that expects to be
90 <     * interrupted
128 >     * Spin-waits until sync.isQueued(t) becomes true.
129       */
130 <    class InterruptedLockRunnable implements Runnable {
131 <        final Mutex lock;
132 <        InterruptedLockRunnable(Mutex l) { lock = l; }
133 <        public void run() {
134 <            try {
135 <                lock.acquireExclusiveInterruptibly(1);
98 <                threadShouldThrow();
99 <            } catch(InterruptedException success){}
130 >    void waitForQueuedThread(AbstractQueuedSynchronizer sync, Thread t) {
131 >        long startTime = System.nanoTime();
132 >        while (!sync.isQueued(t)) {
133 >            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
134 >                throw new AssertionFailedError("timed out");
135 >            Thread.yield();
136          }
137 +        assertTrue(t.isAlive());
138      }
139 <    
139 >
140      /**
141 <     * acquireExclusiveUninterruptiblying an releaseExclusiveed lock succeeds
141 >     * Checks that sync has exactly the given queued threads.
142       */
143 <    public void testAcquireExclusiveUninterruptibly() {
144 <        Mutex rl = new Mutex();
145 <        rl.acquireExclusiveUninterruptibly(1);
146 <        assertTrue(rl.isLocked());
147 <        rl.releaseExclusive(1);
143 >    void assertHasQueuedThreads(AbstractQueuedSynchronizer sync,
144 >                                Thread... expected) {
145 >        Collection<Thread> actual = sync.getQueuedThreads();
146 >        assertEquals(expected.length > 0, sync.hasQueuedThreads());
147 >        assertEquals(expected.length, sync.getQueueLength());
148 >        assertEquals(expected.length, actual.size());
149 >        assertEquals(expected.length == 0, actual.isEmpty());
150 >        assertEquals(new HashSet<Thread>(actual),
151 >                     new HashSet<Thread>(Arrays.asList(expected)));
152      }
153  
154      /**
155 <     * tryAcquireExclusive on an releaseExclusiveed lock succeeds
155 >     * Checks that sync has exactly the given (exclusive) queued threads.
156       */
157 <    public void testTryAcquireExclusive() {
158 <        Mutex rl = new Mutex();
159 <        assertTrue(rl.tryAcquireExclusive(1));
160 <        assertTrue(rl.isLocked());
161 <        rl.releaseExclusive(1);
157 >    void assertHasExclusiveQueuedThreads(AbstractQueuedSynchronizer sync,
158 >                                         Thread... expected) {
159 >        assertHasQueuedThreads(sync, expected);
160 >        assertEquals(new HashSet<Thread>(sync.getExclusiveQueuedThreads()),
161 >                     new HashSet<Thread>(sync.getQueuedThreads()));
162 >        assertEquals(0, sync.getSharedQueuedThreads().size());
163 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
164      }
165  
166      /**
167 <     * hasQueuedThreads reports whether there are waiting threads
167 >     * Checks that sync has exactly the given (shared) queued threads.
168       */
169 <    public void testhasQueuedThreads() {
170 <        final Mutex lock = new Mutex();
171 <        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
172 <        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
173 <        try {
174 <            assertFalse(lock.hasQueuedThreads());
175 <            lock.acquireExclusiveUninterruptibly(1);
176 <            t1.start();
134 <            Thread.sleep(SHORT_DELAY_MS);
135 <            assertTrue(lock.hasQueuedThreads());
136 <            t2.start();
137 <            Thread.sleep(SHORT_DELAY_MS);
138 <            assertTrue(lock.hasQueuedThreads());
139 <            t1.interrupt();
140 <            Thread.sleep(SHORT_DELAY_MS);
141 <            assertTrue(lock.hasQueuedThreads());
142 <            lock.releaseExclusive(1);
143 <            Thread.sleep(SHORT_DELAY_MS);
144 <            assertFalse(lock.hasQueuedThreads());
145 <            t1.join();
146 <            t2.join();
147 <        } catch(Exception e){
148 <            unexpectedException();
149 <        }
150 <    }
151 <
152 <    /**
153 <     * isQueued(null) throws NPE
154 <     */
155 <    public void testIsQueuedNPE() {
156 <        final Mutex lock = new Mutex();
157 <        try {
158 <            lock.isQueued(null);
159 <            shouldThrow();
160 <        } catch (NullPointerException success) {
161 <        }
162 <    }
163 <
164 <    /**
165 <     * isQueued reports whether a thread is queued.
166 <     */
167 <    public void testIsQueued() {
168 <        final Mutex lock = new Mutex();
169 <        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
170 <        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
171 <        try {
172 <            assertFalse(lock.isQueued(t1));
173 <            assertFalse(lock.isQueued(t2));
174 <            lock.acquireExclusiveUninterruptibly(1);
175 <            t1.start();
176 <            Thread.sleep(SHORT_DELAY_MS);
177 <            assertTrue(lock.isQueued(t1));
178 <            t2.start();
179 <            Thread.sleep(SHORT_DELAY_MS);
180 <            assertTrue(lock.isQueued(t1));
181 <            assertTrue(lock.isQueued(t2));
182 <            t1.interrupt();
183 <            Thread.sleep(SHORT_DELAY_MS);
184 <            assertFalse(lock.isQueued(t1));
185 <            assertTrue(lock.isQueued(t2));
186 <            lock.releaseExclusive(1);
187 <            Thread.sleep(SHORT_DELAY_MS);
188 <            assertFalse(lock.isQueued(t1));
189 <            assertFalse(lock.isQueued(t2));
190 <            t1.join();
191 <            t2.join();
192 <        } catch(Exception e){
193 <            unexpectedException();
194 <        }
195 <    }
196 <
197 <    /**
198 <     * getFirstQueuedThread returns first waiting thread or null is none
199 <     */
200 <    public void testGetFirstQueuedThread() {
201 <        final Mutex lock = new Mutex();
202 <        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
203 <        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
204 <        try {
205 <            assertNull(lock.getFirstQueuedThread());
206 <            lock.acquireExclusiveUninterruptibly(1);
207 <            t1.start();
208 <            Thread.sleep(SHORT_DELAY_MS);
209 <            assertEquals(t1, lock.getFirstQueuedThread());
210 <            t2.start();
211 <            Thread.sleep(SHORT_DELAY_MS);
212 <            assertEquals(t1, lock.getFirstQueuedThread());
213 <            t1.interrupt();
214 <            Thread.sleep(SHORT_DELAY_MS);
215 <            assertEquals(t2, lock.getFirstQueuedThread());
216 <            lock.releaseExclusive(1);
217 <            Thread.sleep(SHORT_DELAY_MS);
218 <            assertNull(lock.getFirstQueuedThread());
219 <            t1.join();
220 <            t2.join();
221 <        } catch(Exception e){
222 <            unexpectedException();
223 <        }
224 <    }
169 >    void assertHasSharedQueuedThreads(AbstractQueuedSynchronizer sync,
170 >                                      Thread... expected) {
171 >        assertHasQueuedThreads(sync, expected);
172 >        assertEquals(new HashSet<Thread>(sync.getSharedQueuedThreads()),
173 >                     new HashSet<Thread>(sync.getQueuedThreads()));
174 >        assertEquals(0, sync.getExclusiveQueuedThreads().size());
175 >        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
176 >    }
177  
178 +    /**
179 +     * Checks that condition c has exactly the given waiter threads,
180 +     * after acquiring mutex.
181 +     */
182 +    void assertHasWaitersUnlocked(Mutex sync, ConditionObject c,
183 +                                 Thread... threads) {
184 +        sync.acquire();
185 +        assertHasWaitersLocked(sync, c, threads);
186 +        sync.release();
187 +    }
188  
189      /**
190 <     * hasContended reports false if no thread has ever blocked, else true
190 >     * Checks that condition c has exactly the given waiter threads.
191       */
192 <    public void testHasContended() {
193 <        final Mutex lock = new Mutex();
194 <        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
195 <        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
196 <        try {
197 <            assertFalse(lock.hasContended());
198 <            lock.acquireExclusiveUninterruptibly(1);
199 <            t1.start();
238 <            Thread.sleep(SHORT_DELAY_MS);
239 <            assertTrue(lock.hasContended());
240 <            t2.start();
241 <            Thread.sleep(SHORT_DELAY_MS);
242 <            assertTrue(lock.hasContended());
243 <            t1.interrupt();
244 <            Thread.sleep(SHORT_DELAY_MS);
245 <            assertTrue(lock.hasContended());
246 <            lock.releaseExclusive(1);
247 <            Thread.sleep(SHORT_DELAY_MS);
248 <            assertTrue(lock.hasContended());
249 <            t1.join();
250 <            t2.join();
251 <        } catch(Exception e){
252 <            unexpectedException();
253 <        }
254 <    }
255 <
256 <    /**
257 <     * timed tryAcquireExclusive is interruptible.
258 <     */
259 <    public void testInterruptedException2() {
260 <        final Mutex lock = new Mutex();
261 <        lock.acquireExclusiveUninterruptibly(1);
262 <        Thread t = new Thread(new Runnable() {
263 <                public void run() {
264 <                    try {
265 <                        lock.acquireExclusiveNanos(1, MEDIUM_DELAY_MS * 1000 * 1000);
266 <                        threadShouldThrow();
267 <                    } catch(InterruptedException success){}
268 <                }
269 <            });
270 <        try {
271 <            t.start();
272 <            t.interrupt();
273 <        } catch(Exception e){
274 <            unexpectedException();
275 <        }
192 >    void assertHasWaitersLocked(Mutex sync, ConditionObject c,
193 >                                Thread... threads) {
194 >        assertEquals(threads.length > 0, sync.hasWaiters(c));
195 >        assertEquals(threads.length, sync.getWaitQueueLength(c));
196 >        assertEquals(threads.length == 0, sync.getWaitingThreads(c).isEmpty());
197 >        assertEquals(threads.length, sync.getWaitingThreads(c).size());
198 >        assertEquals(new HashSet<Thread>(sync.getWaitingThreads(c)),
199 >                     new HashSet<Thread>(Arrays.asList(threads)));
200      }
201  
202 +    enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil };
203  
204      /**
205 <     * TryAcquireExclusive on a locked lock fails
206 <     */
207 <    public void testTryAcquireExclusiveWhenLocked() {
208 <        final Mutex lock = new Mutex();
209 <        lock.acquireExclusiveUninterruptibly(1);
210 <        Thread t = new Thread(new Runnable() {
211 <                public void run() {
212 <                    threadAssertFalse(lock.tryAcquireExclusive(1));
213 <                }
214 <            });
215 <        try {
216 <            t.start();
217 <            t.join();
218 <            lock.releaseExclusive(1);
219 <        } catch(Exception e){
220 <            unexpectedException();
221 <        }
222 <    }
223 <
224 <    /**
300 <     * acquireExclusiveTimed on a locked lock times out
301 <     */
302 <    public void testacquireExclusiveTimed_Timeout() {
303 <        final Mutex lock = new Mutex();
304 <        lock.acquireExclusiveUninterruptibly(1);
305 <        Thread t = new Thread(new Runnable() {
306 <                public void run() {
307 <                    try {
308 <                        threadAssertFalse(lock.acquireExclusiveNanos(1, 1000 * 1000));
309 <                    } catch (Exception ex) {
310 <                        threadUnexpectedException();
311 <                    }
312 <                }
313 <            });
314 <        try {
315 <            t.start();
316 <            t.join();
317 <            lock.releaseExclusive(1);
318 <        } catch(Exception e){
319 <            unexpectedException();
320 <        }
321 <    }
322 <    
323 <  
324 <    /**
325 <     * isLocked is true when locked and false when not
326 <     */
327 <    public void testIsLocked() {
328 <        final Mutex lock = new Mutex();
329 <        lock.acquireExclusiveUninterruptibly(1);
330 <        assertTrue(lock.isLocked());
331 <        lock.releaseExclusive(1);
332 <        assertFalse(lock.isLocked());
333 <        Thread t = new Thread(new Runnable() {
334 <                public void run() {
335 <                    lock.acquireExclusiveUninterruptibly(1);
336 <                    try {
337 <                        Thread.sleep(SMALL_DELAY_MS);
338 <                    }
339 <                    catch(Exception e) {
340 <                        threadUnexpectedException();
341 <                    }
342 <                    lock.releaseExclusive(1);
343 <                }
344 <            });
345 <        try {
346 <            t.start();
347 <            Thread.sleep(SHORT_DELAY_MS);
348 <            assertTrue(lock.isLocked());
349 <            t.join();
350 <            assertFalse(lock.isLocked());
351 <        } catch(Exception e){
352 <            unexpectedException();
205 >     * Awaits condition using the specified AwaitMethod.
206 >     */
207 >    void await(ConditionObject c, AwaitMethod awaitMethod)
208 >            throws InterruptedException {
209 >        long timeoutMillis = 2 * LONG_DELAY_MS;
210 >        switch (awaitMethod) {
211 >        case await:
212 >            c.await();
213 >            break;
214 >        case awaitTimed:
215 >            assertTrue(c.await(timeoutMillis, MILLISECONDS));
216 >            break;
217 >        case awaitNanos:
218 >            long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
219 >            long nanosRemaining = c.awaitNanos(nanosTimeout);
220 >            assertTrue(nanosRemaining > 0);
221 >            break;
222 >        case awaitUntil:
223 >            assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
224 >            break;
225          }
226      }
227  
228 +    /**
229 +     * Checks that awaiting the given condition times out (using the
230 +     * default timeout duration).
231 +     */
232 +    void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
233 +        long timeoutMillis = timeoutMillis();
234 +        long startTime = System.nanoTime();
235 +        try {
236 +            switch (awaitMethod) {
237 +            case awaitTimed:
238 +                assertFalse(c.await(timeoutMillis, MILLISECONDS));
239 +                break;
240 +            case awaitNanos:
241 +                long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
242 +                long nanosRemaining = c.awaitNanos(nanosTimeout);
243 +                assertTrue(nanosRemaining <= 0);
244 +                break;
245 +            case awaitUntil:
246 +                assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
247 +                break;
248 +            default:
249 +                throw new UnsupportedOperationException();
250 +            }
251 +        } catch (InterruptedException ie) { threadUnexpectedException(ie); }
252 +        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
253 +    }
254  
255      /**
256 <     * acquireExclusiveInterruptibly is interruptible.
257 <     */
258 <    public void testAcquireInterruptibly1() {
259 <        final Mutex lock = new Mutex();
260 <        lock.acquireExclusiveUninterruptibly(1);
363 <        Thread t = new Thread(new InterruptedLockRunnable(lock));
364 <        try {
365 <            t.start();
366 <            t.interrupt();
367 <            lock.releaseExclusive(1);
368 <            t.join();
369 <        } catch(Exception e){
370 <            unexpectedException();
371 <        }
372 <    }
373 <
374 <    /**
375 <     * acquireExclusiveInterruptibly succeeds when released, else is interruptible
376 <     */
377 <    public void testAcquireInterruptibly2() {
378 <        final Mutex lock = new Mutex();
379 <        try {
380 <            lock.acquireExclusiveInterruptibly(1);
381 <        } catch(Exception e) {
382 <            unexpectedException();
383 <        }
384 <        Thread t = new Thread(new InterruptedLockRunnable(lock));
385 <        try {
386 <            t.start();
387 <            t.interrupt();
388 <            assertTrue(lock.isLocked());
389 <            t.join();
390 <        } catch(Exception e){
391 <            unexpectedException();
392 <        }
256 >     * isHeldExclusively is false upon construction
257 >     */
258 >    public void testIsHeldExclusively() {
259 >        Mutex sync = new Mutex();
260 >        assertFalse(sync.isHeldExclusively());
261      }
262  
263      /**
264 <     * owns is true for a condition created by lock else false
264 >     * acquiring released sync succeeds
265       */
266 <    public void testOwns() {
267 <        final Mutex lock = new Mutex();
268 <        final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition();
269 <        final Mutex lock2 = new Mutex();
270 <        assertTrue(lock.owns(c));
271 <        assertFalse(lock2.owns(c));
266 >    public void testAcquire() {
267 >        Mutex sync = new Mutex();
268 >        sync.acquire();
269 >        assertTrue(sync.isHeldExclusively());
270 >        sync.release();
271 >        assertFalse(sync.isHeldExclusively());
272      }
273  
274      /**
275 <     * Calling await without holding lock throws IllegalMonitorStateException
275 >     * tryAcquire on a released sync succeeds
276       */
277 <    public void testAwait_IllegalMonitor() {
278 <        final Mutex lock = new Mutex();
279 <        final Condition c = lock.newCondition();
277 >    public void testTryAcquire() {
278 >        Mutex sync = new Mutex();
279 >        assertTrue(sync.tryAcquire());
280 >        assertTrue(sync.isHeldExclusively());
281 >        sync.release();
282 >        assertFalse(sync.isHeldExclusively());
283 >    }
284 >
285 >    /**
286 >     * hasQueuedThreads reports whether there are waiting threads
287 >     */
288 >    public void testHasQueuedThreads() {
289 >        final Mutex sync = new Mutex();
290 >        assertFalse(sync.hasQueuedThreads());
291 >        sync.acquire();
292 >        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
293 >        waitForQueuedThread(sync, t1);
294 >        assertTrue(sync.hasQueuedThreads());
295 >        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
296 >        waitForQueuedThread(sync, t2);
297 >        assertTrue(sync.hasQueuedThreads());
298 >        t1.interrupt();
299 >        awaitTermination(t1);
300 >        assertTrue(sync.hasQueuedThreads());
301 >        sync.release();
302 >        awaitTermination(t2);
303 >        assertFalse(sync.hasQueuedThreads());
304 >    }
305 >
306 >    /**
307 >     * isQueued(null) throws NullPointerException
308 >     */
309 >    public void testIsQueuedNPE() {
310 >        final Mutex sync = new Mutex();
311          try {
312 <            c.await();
312 >            sync.isQueued(null);
313              shouldThrow();
314 <        }
315 <        catch (IllegalMonitorStateException success) {
316 <        }
317 <        catch (Exception ex) {
318 <            unexpectedException();
314 >        } catch (NullPointerException success) {}
315 >    }
316 >
317 >    /**
318 >     * isQueued reports whether a thread is queued
319 >     */
320 >    public void testIsQueued() {
321 >        final Mutex sync = new Mutex();
322 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
323 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
324 >        assertFalse(sync.isQueued(t1));
325 >        assertFalse(sync.isQueued(t2));
326 >        sync.acquire();
327 >        t1.start();
328 >        waitForQueuedThread(sync, t1);
329 >        assertTrue(sync.isQueued(t1));
330 >        assertFalse(sync.isQueued(t2));
331 >        t2.start();
332 >        waitForQueuedThread(sync, t2);
333 >        assertTrue(sync.isQueued(t1));
334 >        assertTrue(sync.isQueued(t2));
335 >        t1.interrupt();
336 >        awaitTermination(t1);
337 >        assertFalse(sync.isQueued(t1));
338 >        assertTrue(sync.isQueued(t2));
339 >        sync.release();
340 >        awaitTermination(t2);
341 >        assertFalse(sync.isQueued(t1));
342 >        assertFalse(sync.isQueued(t2));
343 >    }
344 >
345 >    /**
346 >     * getFirstQueuedThread returns first waiting thread or null if none
347 >     */
348 >    public void testGetFirstQueuedThread() {
349 >        final Mutex sync = new Mutex();
350 >        assertNull(sync.getFirstQueuedThread());
351 >        sync.acquire();
352 >        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
353 >        waitForQueuedThread(sync, t1);
354 >        assertEquals(t1, sync.getFirstQueuedThread());
355 >        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
356 >        waitForQueuedThread(sync, t2);
357 >        assertEquals(t1, sync.getFirstQueuedThread());
358 >        t1.interrupt();
359 >        awaitTermination(t1);
360 >        assertEquals(t2, sync.getFirstQueuedThread());
361 >        sync.release();
362 >        awaitTermination(t2);
363 >        assertNull(sync.getFirstQueuedThread());
364 >    }
365 >
366 >    /**
367 >     * hasContended reports false if no thread has ever blocked, else true
368 >     */
369 >    public void testHasContended() {
370 >        final Mutex sync = new Mutex();
371 >        assertFalse(sync.hasContended());
372 >        sync.acquire();
373 >        assertFalse(sync.hasContended());
374 >        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
375 >        waitForQueuedThread(sync, t1);
376 >        assertTrue(sync.hasContended());
377 >        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
378 >        waitForQueuedThread(sync, t2);
379 >        assertTrue(sync.hasContended());
380 >        t1.interrupt();
381 >        awaitTermination(t1);
382 >        assertTrue(sync.hasContended());
383 >        sync.release();
384 >        awaitTermination(t2);
385 >        assertTrue(sync.hasContended());
386 >    }
387 >
388 >    /**
389 >     * getQueuedThreads returns all waiting threads
390 >     */
391 >    public void testGetQueuedThreads() {
392 >        final Mutex sync = new Mutex();
393 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
394 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
395 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
396 >        sync.acquire();
397 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
398 >        t1.start();
399 >        waitForQueuedThread(sync, t1);
400 >        assertHasExclusiveQueuedThreads(sync, t1);
401 >        assertTrue(sync.getQueuedThreads().contains(t1));
402 >        assertFalse(sync.getQueuedThreads().contains(t2));
403 >        t2.start();
404 >        waitForQueuedThread(sync, t2);
405 >        assertHasExclusiveQueuedThreads(sync, t1, t2);
406 >        assertTrue(sync.getQueuedThreads().contains(t1));
407 >        assertTrue(sync.getQueuedThreads().contains(t2));
408 >        t1.interrupt();
409 >        awaitTermination(t1);
410 >        assertHasExclusiveQueuedThreads(sync, t2);
411 >        sync.release();
412 >        awaitTermination(t2);
413 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
414 >    }
415 >
416 >    /**
417 >     * getExclusiveQueuedThreads returns all exclusive waiting threads
418 >     */
419 >    public void testGetExclusiveQueuedThreads() {
420 >        final Mutex sync = new Mutex();
421 >        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
422 >        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
423 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
424 >        sync.acquire();
425 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
426 >        t1.start();
427 >        waitForQueuedThread(sync, t1);
428 >        assertHasExclusiveQueuedThreads(sync, t1);
429 >        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
430 >        assertFalse(sync.getExclusiveQueuedThreads().contains(t2));
431 >        t2.start();
432 >        waitForQueuedThread(sync, t2);
433 >        assertHasExclusiveQueuedThreads(sync, t1, t2);
434 >        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
435 >        assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
436 >        t1.interrupt();
437 >        awaitTermination(t1);
438 >        assertHasExclusiveQueuedThreads(sync, t2);
439 >        sync.release();
440 >        awaitTermination(t2);
441 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
442 >    }
443 >
444 >    /**
445 >     * getSharedQueuedThreads does not include exclusively waiting threads
446 >     */
447 >    public void testGetSharedQueuedThreads_Exclusive() {
448 >        final Mutex sync = new Mutex();
449 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
450 >        sync.acquire();
451 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
452 >        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
453 >        waitForQueuedThread(sync, t1);
454 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
455 >        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
456 >        waitForQueuedThread(sync, t2);
457 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
458 >        t1.interrupt();
459 >        awaitTermination(t1);
460 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
461 >        sync.release();
462 >        awaitTermination(t2);
463 >        assertTrue(sync.getSharedQueuedThreads().isEmpty());
464 >    }
465 >
466 >    /**
467 >     * getSharedQueuedThreads returns all shared waiting threads
468 >     */
469 >    public void testGetSharedQueuedThreads_Shared() {
470 >        final BooleanLatch l = new BooleanLatch();
471 >        assertHasSharedQueuedThreads(l, NO_THREADS);
472 >        Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
473 >            public void realRun() throws InterruptedException {
474 >                l.acquireSharedInterruptibly(0);
475 >            }});
476 >        waitForQueuedThread(l, t1);
477 >        assertHasSharedQueuedThreads(l, t1);
478 >        Thread t2 = newStartedThread(new CheckedRunnable() {
479 >            public void realRun() throws InterruptedException {
480 >                l.acquireSharedInterruptibly(0);
481 >            }});
482 >        waitForQueuedThread(l, t2);
483 >        assertHasSharedQueuedThreads(l, t1, t2);
484 >        t1.interrupt();
485 >        awaitTermination(t1);
486 >        assertHasSharedQueuedThreads(l, t2);
487 >        assertTrue(l.releaseShared(0));
488 >        awaitTermination(t2);
489 >        assertHasSharedQueuedThreads(l, NO_THREADS);
490 >    }
491 >
492 >    /**
493 >     * tryAcquireNanos is interruptible
494 >     */
495 >    public void testTryAcquireNanos_Interruptible() {
496 >        final Mutex sync = new Mutex();
497 >        sync.acquire();
498 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
499 >            public void realRun() throws InterruptedException {
500 >                sync.tryAcquireNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
501 >            }});
502 >
503 >        waitForQueuedThread(sync, t);
504 >        t.interrupt();
505 >        awaitTermination(t);
506 >    }
507 >
508 >    /**
509 >     * tryAcquire on exclusively held sync fails
510 >     */
511 >    public void testTryAcquireWhenSynced() {
512 >        final Mutex sync = new Mutex();
513 >        sync.acquire();
514 >        Thread t = newStartedThread(new CheckedRunnable() {
515 >            public void realRun() {
516 >                assertFalse(sync.tryAcquire());
517 >            }});
518 >
519 >        awaitTermination(t);
520 >        sync.release();
521 >    }
522 >
523 >    /**
524 >     * tryAcquireNanos on an exclusively held sync times out
525 >     */
526 >    public void testAcquireNanos_Timeout() {
527 >        final Mutex sync = new Mutex();
528 >        sync.acquire();
529 >        Thread t = newStartedThread(new CheckedRunnable() {
530 >            public void realRun() throws InterruptedException {
531 >                long startTime = System.nanoTime();
532 >                long nanos = MILLISECONDS.toNanos(timeoutMillis());
533 >                assertFalse(sync.tryAcquireNanos(nanos));
534 >                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
535 >            }});
536 >
537 >        awaitTermination(t);
538 >        sync.release();
539 >    }
540 >
541 >    /**
542 >     * getState is true when acquired and false when not
543 >     */
544 >    public void testGetState() {
545 >        final Mutex sync = new Mutex();
546 >        sync.acquire();
547 >        assertTrue(sync.isHeldExclusively());
548 >        sync.release();
549 >        assertFalse(sync.isHeldExclusively());
550 >
551 >        final BooleanLatch acquired = new BooleanLatch();
552 >        final BooleanLatch done = new BooleanLatch();
553 >        Thread t = newStartedThread(new CheckedRunnable() {
554 >            public void realRun() throws InterruptedException {
555 >                sync.acquire();
556 >                assertTrue(acquired.releaseShared(0));
557 >                done.acquireShared(0);
558 >                sync.release();
559 >            }});
560 >
561 >        acquired.acquireShared(0);
562 >        assertTrue(sync.isHeldExclusively());
563 >        assertTrue(done.releaseShared(0));
564 >        awaitTermination(t);
565 >        assertFalse(sync.isHeldExclusively());
566 >    }
567 >
568 >    /**
569 >     * acquireInterruptibly succeeds when released, else is interruptible
570 >     */
571 >    public void testAcquireInterruptibly() throws InterruptedException {
572 >        final Mutex sync = new Mutex();
573 >        final BooleanLatch threadStarted = new BooleanLatch();
574 >        sync.acquireInterruptibly();
575 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
576 >            public void realRun() throws InterruptedException {
577 >                assertTrue(threadStarted.releaseShared(0));
578 >                sync.acquireInterruptibly();
579 >            }});
580 >
581 >        threadStarted.acquireShared(0);
582 >        waitForQueuedThread(sync, t);
583 >        t.interrupt();
584 >        awaitTermination(t);
585 >        assertTrue(sync.isHeldExclusively());
586 >    }
587 >
588 >    /**
589 >     * owns is true for a condition created by sync else false
590 >     */
591 >    public void testOwns() {
592 >        final Mutex sync = new Mutex();
593 >        final ConditionObject c = sync.newCondition();
594 >        final Mutex sync2 = new Mutex();
595 >        assertTrue(sync.owns(c));
596 >        assertFalse(sync2.owns(c));
597 >    }
598 >
599 >    /**
600 >     * Calling await without holding sync throws IllegalMonitorStateException
601 >     */
602 >    public void testAwait_IMSE() {
603 >        final Mutex sync = new Mutex();
604 >        final ConditionObject c = sync.newCondition();
605 >        for (AwaitMethod awaitMethod : AwaitMethod.values()) {
606 >            long startTime = System.nanoTime();
607 >            try {
608 >                await(c, awaitMethod);
609 >                shouldThrow();
610 >            } catch (IllegalMonitorStateException success) {
611 >            } catch (InterruptedException e) { threadUnexpectedException(e); }
612 >            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
613          }
614      }
615  
616      /**
617 <     * Calling signal without holding lock throws IllegalMonitorStateException
617 >     * Calling signal without holding sync throws IllegalMonitorStateException
618       */
619 <    public void testSignal_IllegalMonitor() {
620 <        final Mutex lock = new Mutex();
621 <        final Condition c = lock.newCondition();
619 >    public void testSignal_IMSE() {
620 >        final Mutex sync = new Mutex();
621 >        final ConditionObject c = sync.newCondition();
622          try {
623              c.signal();
624              shouldThrow();
625 <        }
626 <        catch (IllegalMonitorStateException success) {
434 <        }
435 <        catch (Exception ex) {
436 <            unexpectedException();
437 <        }
625 >        } catch (IllegalMonitorStateException success) {}
626 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
627      }
628  
629      /**
630 <     * awaitNanos without a signal times out
630 >     * Calling signalAll without holding sync throws IllegalMonitorStateException
631       */
632 <    public void testAwaitNanos_Timeout() {
633 <        final Mutex lock = new Mutex();
634 <        final Condition c = lock.newCondition();
632 >    public void testSignalAll_IMSE() {
633 >        final Mutex sync = new Mutex();
634 >        final ConditionObject c = sync.newCondition();
635          try {
636 <            lock.acquireExclusiveUninterruptibly(1);
637 <            long t = c.awaitNanos(100);
638 <            assertTrue(t <= 0);
450 <            lock.releaseExclusive(1);
451 <        }
452 <        catch (Exception ex) {
453 <            unexpectedException();
454 <        }
636 >            c.signalAll();
637 >            shouldThrow();
638 >        } catch (IllegalMonitorStateException success) {}
639      }
640  
641      /**
642 <     *  timed await without a signal times out
642 >     * await/awaitNanos/awaitUntil without a signal times out
643       */
644 <    public void testAwait_Timeout() {
645 <        final Mutex lock = new Mutex();
646 <        final Condition c = lock.newCondition();
644 >    public void testAwaitTimed_Timeout() { testAwait_Timeout(AwaitMethod.awaitTimed); }
645 >    public void testAwaitNanos_Timeout() { testAwait_Timeout(AwaitMethod.awaitNanos); }
646 >    public void testAwaitUntil_Timeout() { testAwait_Timeout(AwaitMethod.awaitUntil); }
647 >    public void testAwait_Timeout(AwaitMethod awaitMethod) {
648 >        final Mutex sync = new Mutex();
649 >        final ConditionObject c = sync.newCondition();
650 >        sync.acquire();
651 >        assertAwaitTimesOut(c, awaitMethod);
652 >        sync.release();
653 >    }
654 >
655 >    /**
656 >     * await/awaitNanos/awaitUntil returns when signalled
657 >     */
658 >    public void testSignal_await()      { testSignal(AwaitMethod.await); }
659 >    public void testSignal_awaitTimed() { testSignal(AwaitMethod.awaitTimed); }
660 >    public void testSignal_awaitNanos() { testSignal(AwaitMethod.awaitNanos); }
661 >    public void testSignal_awaitUntil() { testSignal(AwaitMethod.awaitUntil); }
662 >    public void testSignal(final AwaitMethod awaitMethod) {
663 >        final Mutex sync = new Mutex();
664 >        final ConditionObject c = sync.newCondition();
665 >        final BooleanLatch acquired = new BooleanLatch();
666 >        Thread t = newStartedThread(new CheckedRunnable() {
667 >            public void realRun() throws InterruptedException {
668 >                sync.acquire();
669 >                assertTrue(acquired.releaseShared(0));
670 >                await(c, awaitMethod);
671 >                sync.release();
672 >            }});
673 >
674 >        acquired.acquireShared(0);
675 >        sync.acquire();
676 >        assertHasWaitersLocked(sync, c, t);
677 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
678 >        c.signal();
679 >        assertHasWaitersLocked(sync, c, NO_THREADS);
680 >        assertHasExclusiveQueuedThreads(sync, t);
681 >        sync.release();
682 >        awaitTermination(t);
683 >    }
684 >
685 >    /**
686 >     * hasWaiters(null) throws NullPointerException
687 >     */
688 >    public void testHasWaitersNPE() {
689 >        final Mutex sync = new Mutex();
690          try {
691 <            lock.acquireExclusiveUninterruptibly(1);
692 <            assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
693 <            lock.releaseExclusive(1);
467 <        }
468 <        catch (Exception ex) {
469 <            unexpectedException();
470 <        }
691 >            sync.hasWaiters(null);
692 >            shouldThrow();
693 >        } catch (NullPointerException success) {}
694      }
695  
696      /**
697 <     * awaitUntil without a signal times out
697 >     * getWaitQueueLength(null) throws NullPointerException
698       */
699 <    public void testAwaitUntil_Timeout() {
700 <        final Mutex lock = new Mutex();
478 <        final Condition c = lock.newCondition();
699 >    public void testGetWaitQueueLengthNPE() {
700 >        final Mutex sync = new Mutex();
701          try {
702 <            lock.acquireExclusiveUninterruptibly(1);
703 <            java.util.Date d = new java.util.Date();
704 <            assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
483 <            lock.releaseExclusive(1);
484 <        }
485 <        catch (Exception ex) {
486 <            unexpectedException();
487 <        }
702 >            sync.getWaitQueueLength(null);
703 >            shouldThrow();
704 >        } catch (NullPointerException success) {}
705      }
706  
707      /**
708 <     * await returns when signalled
708 >     * getWaitingThreads(null) throws NullPointerException
709       */
710 <    public void testAwait() {
711 <        final Mutex lock = new Mutex();
712 <        final Condition c = lock.newCondition();
713 <        Thread t = new Thread(new Runnable() {
714 <                public void run() {
715 <                    try {
716 <                        lock.acquireExclusiveUninterruptibly(1);
500 <                        c.await();
501 <                        lock.releaseExclusive(1);
502 <                    }
503 <                    catch(InterruptedException e) {
504 <                        threadUnexpectedException();
505 <                    }
506 <                }
507 <            });
710 >    public void testGetWaitingThreadsNPE() {
711 >        final Mutex sync = new Mutex();
712 >        try {
713 >            sync.getWaitingThreads(null);
714 >            shouldThrow();
715 >        } catch (NullPointerException success) {}
716 >    }
717  
718 +    /**
719 +     * hasWaiters throws IllegalArgumentException if not owned
720 +     */
721 +    public void testHasWaitersIAE() {
722 +        final Mutex sync = new Mutex();
723 +        final ConditionObject c = sync.newCondition();
724 +        final Mutex sync2 = new Mutex();
725          try {
726 <            t.start();
727 <            Thread.sleep(SHORT_DELAY_MS);
728 <            lock.acquireExclusiveUninterruptibly(1);
729 <            c.signal();
730 <            lock.releaseExclusive(1);
731 <            t.join(SHORT_DELAY_MS);
732 <            assertFalse(t.isAlive());
733 <        }
734 <        catch (Exception ex) {
735 <            unexpectedException();
736 <        }
726 >            sync2.hasWaiters(c);
727 >            shouldThrow();
728 >        } catch (IllegalArgumentException success) {}
729 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
730 >    }
731 >
732 >    /**
733 >     * hasWaiters throws IllegalMonitorStateException if not synced
734 >     */
735 >    public void testHasWaitersIMSE() {
736 >        final Mutex sync = new Mutex();
737 >        final ConditionObject c = sync.newCondition();
738 >        try {
739 >            sync.hasWaiters(c);
740 >            shouldThrow();
741 >        } catch (IllegalMonitorStateException success) {}
742 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
743 >    }
744 >
745 >    /**
746 >     * getWaitQueueLength throws IllegalArgumentException if not owned
747 >     */
748 >    public void testGetWaitQueueLengthIAE() {
749 >        final Mutex sync = new Mutex();
750 >        final ConditionObject c = sync.newCondition();
751 >        final Mutex sync2 = new Mutex();
752 >        try {
753 >            sync2.getWaitQueueLength(c);
754 >            shouldThrow();
755 >        } catch (IllegalArgumentException success) {}
756 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
757 >    }
758 >
759 >    /**
760 >     * getWaitQueueLength throws IllegalMonitorStateException if not synced
761 >     */
762 >    public void testGetWaitQueueLengthIMSE() {
763 >        final Mutex sync = new Mutex();
764 >        final ConditionObject c = sync.newCondition();
765 >        try {
766 >            sync.getWaitQueueLength(c);
767 >            shouldThrow();
768 >        } catch (IllegalMonitorStateException success) {}
769 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
770 >    }
771 >
772 >    /**
773 >     * getWaitingThreads throws IllegalArgumentException if not owned
774 >     */
775 >    public void testGetWaitingThreadsIAE() {
776 >        final Mutex sync = new Mutex();
777 >        final ConditionObject c = sync.newCondition();
778 >        final Mutex sync2 = new Mutex();
779 >        try {
780 >            sync2.getWaitingThreads(c);
781 >            shouldThrow();
782 >        } catch (IllegalArgumentException success) {}
783 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
784      }
785  
786 +    /**
787 +     * getWaitingThreads throws IllegalMonitorStateException if not synced
788 +     */
789 +    public void testGetWaitingThreadsIMSE() {
790 +        final Mutex sync = new Mutex();
791 +        final ConditionObject c = sync.newCondition();
792 +        try {
793 +            sync.getWaitingThreads(c);
794 +            shouldThrow();
795 +        } catch (IllegalMonitorStateException success) {}
796 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
797 +    }
798 +
799 +    /**
800 +     * hasWaiters returns true when a thread is waiting, else false
801 +     */
802 +    public void testHasWaiters() {
803 +        final Mutex sync = new Mutex();
804 +        final ConditionObject c = sync.newCondition();
805 +        final BooleanLatch acquired = new BooleanLatch();
806 +        Thread t = newStartedThread(new CheckedRunnable() {
807 +            public void realRun() throws InterruptedException {
808 +                sync.acquire();
809 +                assertHasWaitersLocked(sync, c, NO_THREADS);
810 +                assertFalse(sync.hasWaiters(c));
811 +                assertTrue(acquired.releaseShared(0));
812 +                c.await();
813 +                sync.release();
814 +            }});
815 +
816 +        acquired.acquireShared(0);
817 +        sync.acquire();
818 +        assertHasWaitersLocked(sync, c, t);
819 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
820 +        assertTrue(sync.hasWaiters(c));
821 +        c.signal();
822 +        assertHasWaitersLocked(sync, c, NO_THREADS);
823 +        assertHasExclusiveQueuedThreads(sync, t);
824 +        assertFalse(sync.hasWaiters(c));
825 +        sync.release();
826 +
827 +        awaitTermination(t);
828 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
829 +    }
830 +
831 +    /**
832 +     * getWaitQueueLength returns number of waiting threads
833 +     */
834 +    public void testGetWaitQueueLength() {
835 +        final Mutex sync = new Mutex();
836 +        final ConditionObject c = sync.newCondition();
837 +        final BooleanLatch acquired1 = new BooleanLatch();
838 +        final BooleanLatch acquired2 = new BooleanLatch();
839 +        final Thread t1 = newStartedThread(new CheckedRunnable() {
840 +            public void realRun() throws InterruptedException {
841 +                sync.acquire();
842 +                assertHasWaitersLocked(sync, c, NO_THREADS);
843 +                assertEquals(0, sync.getWaitQueueLength(c));
844 +                assertTrue(acquired1.releaseShared(0));
845 +                c.await();
846 +                sync.release();
847 +            }});
848 +        acquired1.acquireShared(0);
849 +        sync.acquire();
850 +        assertHasWaitersLocked(sync, c, t1);
851 +        assertEquals(1, sync.getWaitQueueLength(c));
852 +        sync.release();
853 +
854 +        final Thread t2 = newStartedThread(new CheckedRunnable() {
855 +            public void realRun() throws InterruptedException {
856 +                sync.acquire();
857 +                assertHasWaitersLocked(sync, c, t1);
858 +                assertEquals(1, sync.getWaitQueueLength(c));
859 +                assertTrue(acquired2.releaseShared(0));
860 +                c.await();
861 +                sync.release();
862 +            }});
863 +        acquired2.acquireShared(0);
864 +        sync.acquire();
865 +        assertHasWaitersLocked(sync, c, t1, t2);
866 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
867 +        assertEquals(2, sync.getWaitQueueLength(c));
868 +        c.signalAll();
869 +        assertHasWaitersLocked(sync, c, NO_THREADS);
870 +        assertHasExclusiveQueuedThreads(sync, t1, t2);
871 +        assertEquals(0, sync.getWaitQueueLength(c));
872 +        sync.release();
873 +
874 +        awaitTermination(t1);
875 +        awaitTermination(t2);
876 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
877 +    }
878 +
879 +    /**
880 +     * getWaitingThreads returns only and all waiting threads
881 +     */
882 +    public void testGetWaitingThreads() {
883 +        final Mutex sync = new Mutex();
884 +        final ConditionObject c = sync.newCondition();
885 +        final BooleanLatch acquired1 = new BooleanLatch();
886 +        final BooleanLatch acquired2 = new BooleanLatch();
887 +        final Thread t1 = new Thread(new CheckedRunnable() {
888 +            public void realRun() throws InterruptedException {
889 +                sync.acquire();
890 +                assertHasWaitersLocked(sync, c, NO_THREADS);
891 +                assertTrue(sync.getWaitingThreads(c).isEmpty());
892 +                assertTrue(acquired1.releaseShared(0));
893 +                c.await();
894 +                sync.release();
895 +            }});
896 +
897 +        final Thread t2 = new Thread(new CheckedRunnable() {
898 +            public void realRun() throws InterruptedException {
899 +                sync.acquire();
900 +                assertHasWaitersLocked(sync, c, t1);
901 +                assertTrue(sync.getWaitingThreads(c).contains(t1));
902 +                assertFalse(sync.getWaitingThreads(c).isEmpty());
903 +                assertEquals(1, sync.getWaitingThreads(c).size());
904 +                assertTrue(acquired2.releaseShared(0));
905 +                c.await();
906 +                sync.release();
907 +            }});
908 +
909 +        sync.acquire();
910 +        assertHasWaitersLocked(sync, c, NO_THREADS);
911 +        assertFalse(sync.getWaitingThreads(c).contains(t1));
912 +        assertFalse(sync.getWaitingThreads(c).contains(t2));
913 +        assertTrue(sync.getWaitingThreads(c).isEmpty());
914 +        assertEquals(0, sync.getWaitingThreads(c).size());
915 +        sync.release();
916 +
917 +        t1.start();
918 +        acquired1.acquireShared(0);
919 +        sync.acquire();
920 +        assertHasWaitersLocked(sync, c, t1);
921 +        assertTrue(sync.getWaitingThreads(c).contains(t1));
922 +        assertFalse(sync.getWaitingThreads(c).contains(t2));
923 +        assertFalse(sync.getWaitingThreads(c).isEmpty());
924 +        assertEquals(1, sync.getWaitingThreads(c).size());
925 +        sync.release();
926 +
927 +        t2.start();
928 +        acquired2.acquireShared(0);
929 +        sync.acquire();
930 +        assertHasWaitersLocked(sync, c, t1, t2);
931 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
932 +        assertTrue(sync.getWaitingThreads(c).contains(t1));
933 +        assertTrue(sync.getWaitingThreads(c).contains(t2));
934 +        assertFalse(sync.getWaitingThreads(c).isEmpty());
935 +        assertEquals(2, sync.getWaitingThreads(c).size());
936 +        c.signalAll();
937 +        assertHasWaitersLocked(sync, c, NO_THREADS);
938 +        assertHasExclusiveQueuedThreads(sync, t1, t2);
939 +        assertFalse(sync.getWaitingThreads(c).contains(t1));
940 +        assertFalse(sync.getWaitingThreads(c).contains(t2));
941 +        assertTrue(sync.getWaitingThreads(c).isEmpty());
942 +        assertEquals(0, sync.getWaitingThreads(c).size());
943 +        sync.release();
944 +
945 +        awaitTermination(t1);
946 +        awaitTermination(t2);
947 +        assertHasWaitersUnlocked(sync, c, NO_THREADS);
948 +    }
949 +
950 +    /**
951 +     * awaitUninterruptibly is uninterruptible
952 +     */
953 +    public void testAwaitUninterruptibly() {
954 +        final Mutex sync = new Mutex();
955 +        final ConditionObject c = sync.newCondition();
956 +        final BooleanLatch pleaseInterrupt = new BooleanLatch();
957 +        Thread t = newStartedThread(new CheckedRunnable() {
958 +            public void realRun() {
959 +                sync.acquire();
960 +                assertTrue(pleaseInterrupt.releaseShared(0));
961 +                c.awaitUninterruptibly();
962 +                assertTrue(Thread.interrupted());
963 +                assertHasWaitersLocked(sync, c, NO_THREADS);
964 +                sync.release();
965 +            }});
966 +
967 +        pleaseInterrupt.acquireShared(0);
968 +        sync.acquire();
969 +        assertHasWaitersLocked(sync, c, t);
970 +        sync.release();
971 +        t.interrupt();
972 +        assertHasWaitersUnlocked(sync, c, t);
973 +        assertThreadStaysAlive(t);
974 +        sync.acquire();
975 +        assertHasWaitersLocked(sync, c, t);
976 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
977 +        c.signal();
978 +        assertHasWaitersLocked(sync, c, NO_THREADS);
979 +        assertHasExclusiveQueuedThreads(sync, t);
980 +        sync.release();
981 +        awaitTermination(t);
982 +    }
983 +
984 +    /**
985 +     * await/awaitNanos/awaitUntil is interruptible
986 +     */
987 +    public void testInterruptible_await()      { testInterruptible(AwaitMethod.await); }
988 +    public void testInterruptible_awaitTimed() { testInterruptible(AwaitMethod.awaitTimed); }
989 +    public void testInterruptible_awaitNanos() { testInterruptible(AwaitMethod.awaitNanos); }
990 +    public void testInterruptible_awaitUntil() { testInterruptible(AwaitMethod.awaitUntil); }
991 +    public void testInterruptible(final AwaitMethod awaitMethod) {
992 +        final Mutex sync = new Mutex();
993 +        final ConditionObject c = sync.newCondition();
994 +        final BooleanLatch pleaseInterrupt = new BooleanLatch();
995 +        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
996 +            public void realRun() throws InterruptedException {
997 +                sync.acquire();
998 +                assertTrue(pleaseInterrupt.releaseShared(0));
999 +                await(c, awaitMethod);
1000 +            }});
1001 +
1002 +        pleaseInterrupt.acquireShared(0);
1003 +        t.interrupt();
1004 +        awaitTermination(t);
1005 +    }
1006 +
1007 +    /**
1008 +     * signalAll wakes up all threads
1009 +     */
1010 +    public void testSignalAll_await()      { testSignalAll(AwaitMethod.await); }
1011 +    public void testSignalAll_awaitTimed() { testSignalAll(AwaitMethod.awaitTimed); }
1012 +    public void testSignalAll_awaitNanos() { testSignalAll(AwaitMethod.awaitNanos); }
1013 +    public void testSignalAll_awaitUntil() { testSignalAll(AwaitMethod.awaitUntil); }
1014 +    public void testSignalAll(final AwaitMethod awaitMethod) {
1015 +        final Mutex sync = new Mutex();
1016 +        final ConditionObject c = sync.newCondition();
1017 +        final BooleanLatch acquired1 = new BooleanLatch();
1018 +        final BooleanLatch acquired2 = new BooleanLatch();
1019 +        Thread t1 = newStartedThread(new CheckedRunnable() {
1020 +            public void realRun() throws InterruptedException {
1021 +                sync.acquire();
1022 +                acquired1.releaseShared(0);
1023 +                await(c, awaitMethod);
1024 +                sync.release();
1025 +            }});
1026 +
1027 +        Thread t2 = newStartedThread(new CheckedRunnable() {
1028 +            public void realRun() throws InterruptedException {
1029 +                sync.acquire();
1030 +                acquired2.releaseShared(0);
1031 +                await(c, awaitMethod);
1032 +                sync.release();
1033 +            }});
1034 +
1035 +        acquired1.acquireShared(0);
1036 +        acquired2.acquireShared(0);
1037 +        sync.acquire();
1038 +        assertHasWaitersLocked(sync, c, t1, t2);
1039 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
1040 +        c.signalAll();
1041 +        assertHasWaitersLocked(sync, c, NO_THREADS);
1042 +        assertHasExclusiveQueuedThreads(sync, t1, t2);
1043 +        sync.release();
1044 +        awaitTermination(t1);
1045 +        awaitTermination(t2);
1046 +    }
1047 +
1048 +    /**
1049 +     * toString indicates current state
1050 +     */
1051 +    public void testToString() {
1052 +        Mutex sync = new Mutex();
1053 +        assertTrue(sync.toString().contains("State = " + Mutex.UNLOCKED));
1054 +        sync.acquire();
1055 +        assertTrue(sync.toString().contains("State = " + Mutex.LOCKED));
1056 +    }
1057 +
1058 +    /**
1059 +     * A serialized AQS deserializes with current state, but no queued threads
1060 +     */
1061 +    public void testSerialization() {
1062 +        Mutex sync = new Mutex();
1063 +        assertFalse(serialClone(sync).isHeldExclusively());
1064 +        sync.acquire();
1065 +        Thread t = newStartedThread(new InterruptedSyncRunnable(sync));
1066 +        waitForQueuedThread(sync, t);
1067 +        assertTrue(sync.isHeldExclusively());
1068 +
1069 +        Mutex clone = serialClone(sync);
1070 +        assertTrue(clone.isHeldExclusively());
1071 +        assertHasExclusiveQueuedThreads(sync, t);
1072 +        assertHasExclusiveQueuedThreads(clone, NO_THREADS);
1073 +        t.interrupt();
1074 +        awaitTermination(t);
1075 +        sync.release();
1076 +        assertFalse(sync.isHeldExclusively());
1077 +        assertTrue(clone.isHeldExclusively());
1078 +        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
1079 +        assertHasExclusiveQueuedThreads(clone, NO_THREADS);
1080 +    }
1081  
1082      /**
1083 <     * Latch isSignalled initially returns false, then true after release
1083 >     * tryReleaseShared setting state changes getState
1084       */
1085 <    public void testLatchIsSignalled() {
1086 <        final BooleanLatch l = new BooleanLatch();
1087 <        assertFalse(l.isSignalled());
1088 <        l.releaseShared(0);
1089 <        assertTrue(l.isSignalled());
1085 >    public void testGetStateWithReleaseShared() {
1086 >        final BooleanLatch l = new BooleanLatch();
1087 >        assertFalse(l.isSignalled());
1088 >        assertTrue(l.releaseShared(0));
1089 >        assertTrue(l.isSignalled());
1090      }
1091  
1092      /**
1093 <     * release and has no effect when already signalled
1093 >     * releaseShared has no effect when already signalled
1094       */
1095 <    public void testLatchBoolean() {
1096 <        final BooleanLatch l = new BooleanLatch();
1097 <        assertFalse(l.isSignalled());
1098 <        l.releaseShared(0);
1099 <        assertTrue(l.isSignalled());
1100 <        l.releaseShared(0);
1101 <        assertTrue(l.isSignalled());
1095 >    public void testReleaseShared() {
1096 >        final BooleanLatch l = new BooleanLatch();
1097 >        assertFalse(l.isSignalled());
1098 >        assertTrue(l.releaseShared(0));
1099 >        assertTrue(l.isSignalled());
1100 >        assertTrue(l.releaseShared(0));
1101 >        assertTrue(l.isSignalled());
1102      }
1103  
1104      /**
1105       * acquireSharedInterruptibly returns after release, but not before
1106       */
1107 <    public void testLatchAcquireSharedInterruptibly() {
1108 <        final BooleanLatch l = new BooleanLatch();
1107 >    public void testAcquireSharedInterruptibly() {
1108 >        final BooleanLatch l = new BooleanLatch();
1109  
1110 <        Thread t = new Thread(new Runnable() {
1111 <                public void run() {
1112 <                    try {
1113 <                        threadAssertFalse(l.isSignalled());
1114 <                        l.acquireSharedInterruptibly(0);
1115 <                        threadAssertTrue(l.isSignalled());
1116 <                    } catch(InterruptedException e){
1117 <                        threadUnexpectedException();
1118 <                    }
1119 <                }
1120 <            });
1121 <        try {
1122 <            t.start();
1123 <            assertFalse(l.isSignalled());
1124 <            Thread.sleep(SHORT_DELAY_MS);
1125 <            l.releaseShared(0);
568 <            assertTrue(l.isSignalled());
569 <            t.join();
570 <        } catch (InterruptedException e){
571 <            unexpectedException();
572 <        }
573 <    }
574 <    
575 <
576 <    /**
577 <     * acquireSharedTimed returns after release
578 <     */
579 <    public void testLatchTimedacquireSharedInterruptibly() {
580 <        final BooleanLatch l = new BooleanLatch();
581 <
582 <        Thread t = new Thread(new Runnable() {
583 <                public void run() {
584 <                    try {
585 <                        threadAssertFalse(l.isSignalled());
586 <                        threadAssertTrue(l.acquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
587 <                        threadAssertTrue(l.isSignalled());
588 <
589 <                    } catch(InterruptedException e){
590 <                        threadUnexpectedException();
591 <                    }
592 <                }
593 <            });
594 <        try {
595 <            t.start();
596 <            assertFalse(l.isSignalled());
597 <            Thread.sleep(SHORT_DELAY_MS);
598 <            l.releaseShared(0);
599 <            assertTrue(l.isSignalled());
600 <            t.join();
601 <        } catch (InterruptedException e){
602 <            unexpectedException();
603 <        }
1110 >        Thread t = newStartedThread(new CheckedRunnable() {
1111 >            public void realRun() throws InterruptedException {
1112 >                assertFalse(l.isSignalled());
1113 >                l.acquireSharedInterruptibly(0);
1114 >                assertTrue(l.isSignalled());
1115 >                l.acquireSharedInterruptibly(0);
1116 >                assertTrue(l.isSignalled());
1117 >            }});
1118 >
1119 >        waitForQueuedThread(l, t);
1120 >        assertFalse(l.isSignalled());
1121 >        assertThreadStaysAlive(t);
1122 >        assertHasSharedQueuedThreads(l, t);
1123 >        assertTrue(l.releaseShared(0));
1124 >        assertTrue(l.isSignalled());
1125 >        awaitTermination(t);
1126      }
1127 <    
1127 >
1128      /**
1129 <     * acquireSharedInterruptibly throws IE if interrupted before released
1129 >     * tryAcquireSharedNanos returns after release, but not before
1130       */
1131 <    public void testLatchAcquireSharedInterruptibly_InterruptedException() {
1131 >    public void testTryAcquireSharedNanos() {
1132          final BooleanLatch l = new BooleanLatch();
1133 <        Thread t = new Thread(new Runnable() {
1134 <                public void run() {
1135 <                    try {
1136 <                        threadAssertFalse(l.isSignalled());
1137 <                        l.acquireSharedInterruptibly(0);
1138 <                        threadShouldThrow();
1139 <                    } catch(InterruptedException success){}
1140 <                }
1141 <            });
1142 <        t.start();
1143 <        try {
1144 <            assertFalse(l.isSignalled());
1145 <            t.interrupt();
1146 <            t.join();
1147 <        } catch (InterruptedException e){
1148 <            unexpectedException();
1149 <        }
1133 >
1134 >        Thread t = newStartedThread(new CheckedRunnable() {
1135 >            public void realRun() throws InterruptedException {
1136 >                assertFalse(l.isSignalled());
1137 >                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
1138 >                assertTrue(l.tryAcquireSharedNanos(0, nanos));
1139 >                assertTrue(l.isSignalled());
1140 >                assertTrue(l.tryAcquireSharedNanos(0, nanos));
1141 >                assertTrue(l.isSignalled());
1142 >            }});
1143 >
1144 >        waitForQueuedThread(l, t);
1145 >        assertFalse(l.isSignalled());
1146 >        assertThreadStaysAlive(t);
1147 >        assertTrue(l.releaseShared(0));
1148 >        assertTrue(l.isSignalled());
1149 >        awaitTermination(t);
1150      }
1151  
1152      /**
1153 <     * acquireSharedTimed throws IE if interrupted before released
1153 >     * acquireSharedInterruptibly is interruptible
1154       */
1155 <    public void testLatchTimedAwait_InterruptedException() {
1155 >    public void testAcquireSharedInterruptibly_Interruptible() {
1156          final BooleanLatch l = new BooleanLatch();
1157 <        Thread t = new Thread(new Runnable() {
1158 <                public void run() {
1159 <                    try {
1160 <                        threadAssertFalse(l.isSignalled());
1161 <                        l.acquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
1162 <                        threadShouldThrow();                        
1163 <                    } catch(InterruptedException success){}
1164 <                }
1165 <            });
1166 <        t.start();
1167 <        try {
646 <            Thread.sleep(SHORT_DELAY_MS);
647 <            assertFalse(l.isSignalled());
648 <            t.interrupt();
649 <            t.join();
650 <        } catch (InterruptedException e){
651 <            unexpectedException();
652 <        }
1157 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1158 >            public void realRun() throws InterruptedException {
1159 >                assertFalse(l.isSignalled());
1160 >                l.acquireSharedInterruptibly(0);
1161 >            }});
1162 >
1163 >        waitForQueuedThread(l, t);
1164 >        assertFalse(l.isSignalled());
1165 >        t.interrupt();
1166 >        awaitTermination(t);
1167 >        assertFalse(l.isSignalled());
1168      }
1169  
1170      /**
1171 <     * acquireSharedTimed times out if not released before timeout
1171 >     * tryAcquireSharedNanos is interruptible
1172       */
1173 <    public void testLatchAwaitTimeout() {
1173 >    public void testTryAcquireSharedNanos_Interruptible() {
1174          final BooleanLatch l = new BooleanLatch();
1175 <        Thread t = new Thread(new Runnable() {
1176 <                public void run() {
1177 <                    try {
1178 <                        threadAssertFalse(l.isSignalled());
1179 <                        threadAssertFalse(l.acquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
1180 <                    } catch(InterruptedException ie){
1181 <                        threadUnexpectedException();
1182 <                    }
1175 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1176 >            public void realRun() throws InterruptedException {
1177 >                assertFalse(l.isSignalled());
1178 >                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
1179 >                l.tryAcquireSharedNanos(0, nanos);
1180 >            }});
1181 >
1182 >        waitForQueuedThread(l, t);
1183 >        assertFalse(l.isSignalled());
1184 >        t.interrupt();
1185 >        awaitTermination(t);
1186 >        assertFalse(l.isSignalled());
1187 >    }
1188 >
1189 >    /**
1190 >     * tryAcquireSharedNanos times out if not released before timeout
1191 >     */
1192 >    public void testTryAcquireSharedNanos_Timeout() {
1193 >        final BooleanLatch l = new BooleanLatch();
1194 >        final BooleanLatch observedQueued = new BooleanLatch();
1195 >        final long timeoutMillis = timeoutMillis();
1196 >        Thread t = newStartedThread(new CheckedRunnable() {
1197 >            public void realRun() throws InterruptedException {
1198 >                assertFalse(l.isSignalled());
1199 >                for (long millis = timeoutMillis();
1200 >                     !observedQueued.isSignalled();
1201 >                     millis *= 2) {
1202 >                    long nanos = MILLISECONDS.toNanos(millis);
1203 >                    long startTime = System.nanoTime();
1204 >                    assertFalse(l.tryAcquireSharedNanos(0, nanos));
1205 >                    assertTrue(millisElapsedSince(startTime) >= millis);
1206                  }
1207 <            });
1208 <        t.start();
1209 <        try {
1210 <            Thread.sleep(SHORT_DELAY_MS);
1211 <            assertFalse(l.isSignalled());
1212 <            t.join();
1213 <        } catch (InterruptedException e){
1214 <            unexpectedException();
1215 <        }
1207 >                assertFalse(l.isSignalled());
1208 >            }});
1209 >
1210 >        waitForQueuedThread(l, t);
1211 >        observedQueued.releaseShared(0);
1212 >        assertFalse(l.isSignalled());
1213 >        awaitTermination(t);
1214 >        assertFalse(l.isSignalled());
1215 >    }
1216 >
1217 >    /**
1218 >     * awaitNanos/timed await with 0 wait times out immediately
1219 >     */
1220 >    public void testAwait_Zero() throws InterruptedException {
1221 >        final Mutex sync = new Mutex();
1222 >        final ConditionObject c = sync.newCondition();
1223 >        sync.acquire();
1224 >        assertTrue(c.awaitNanos(0L) <= 0);
1225 >        assertFalse(c.await(0L, NANOSECONDS));
1226 >        sync.release();
1227      }
1228 <    
1228 >
1229 >    /**
1230 >     * awaitNanos/timed await with maximum negative wait times does not underflow
1231 >     */
1232 >    public void testAwait_NegativeInfinity() throws InterruptedException {
1233 >        final Mutex sync = new Mutex();
1234 >        final ConditionObject c = sync.newCondition();
1235 >        sync.acquire();
1236 >        assertTrue(c.awaitNanos(Long.MIN_VALUE) <= 0);
1237 >        assertFalse(c.await(Long.MIN_VALUE, NANOSECONDS));
1238 >        sync.release();
1239 >    }
1240 >
1241   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines