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

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines