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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines