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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines