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.9 by jsr166, Wed Nov 18 08:22:57 2009 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 + import static java.util.concurrent.TimeUnit.MILLISECONDS;
10 + import static java.util.concurrent.TimeUnit.NANOSECONDS;
11  
12 < import junit.framework.*;
13 < import java.util.*;
14 < import java.util.concurrent.*;
15 < import java.util.concurrent.locks.*;
16 < import java.io.*;
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,
30 <     * 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() { 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      }
108  
109      /**
110 <     * A runnable calling acquireInterruptibly
110 >     * A runnable calling acquireInterruptibly that does not expect to
111 >     * be interrupted.
112       */
113 <    class InterruptibleSyncRunnable implements Runnable {
113 >    class InterruptibleSyncRunnable extends CheckedRunnable {
114          final Mutex sync;
115 <        InterruptibleSyncRunnable(Mutex l) { sync = l; }
116 <        public void run() {
117 <            try {
78 <                sync.acquireInterruptibly(1);
79 <            } catch (InterruptedException success) {}
115 >        InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; }
116 >        public void realRun() throws InterruptedException {
117 >            sync.acquireInterruptibly();
118          }
119      }
120  
83
121      /**
122       * A runnable calling acquireInterruptibly that expects to be
123 <     * interrupted
123 >     * interrupted.
124       */
125 <    class InterruptedSyncRunnable implements Runnable {
125 >    class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
126          final Mutex sync;
127 <        InterruptedSyncRunnable(Mutex l) { sync = l; }
128 <        public void run() {
129 <            try {
93 <                sync.acquireInterruptibly(1);
94 <                threadShouldThrow();
95 <            } catch (InterruptedException success) {}
127 >        InterruptedSyncRunnable(Mutex sync) { this.sync = sync; }
128 >        public void realRun() throws InterruptedException {
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 {
309 <        final Mutex sync = new Mutex();
133 <        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
134 <        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
308 >    public void testHasQueuedThreads() {
309 >        final Mutex sync = new Mutex();
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());
149        t1.join();
150        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();
330 >        final Mutex sync = new Mutex();
331          try {
332              sync.isQueued(null);
333              shouldThrow();
# Line 162 | 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 {
341 <        final Mutex sync = new Mutex();
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));
188        Thread.sleep(SHORT_DELAY_MS);
362          assertFalse(sync.isQueued(t2));
190        t1.join();
191        t2.join();
363      }
364  
365      /**
366       * getFirstQueuedThread returns first waiting thread or null if none
367       */
368 <    public void testGetFirstQueuedThread() throws InterruptedException {
369 <        final Mutex sync = new Mutex();
199 <        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
200 <        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
368 >    public void testGetFirstQueuedThread() {
369 >        final Mutex sync = new Mutex();
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);
211 <        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());
216        t1.join();
217        t2.join();
384      }
385  
220
386      /**
387       * hasContended reports false if no thread has ever blocked, else true
388       */
389 <    public void testHasContended() throws InterruptedException {
390 <        final Mutex sync = new Mutex();
226 <        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
227 <        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
389 >    public void testHasContended() {
390 >        final Mutex sync = new Mutex();
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());
242        t1.join();
243        t2.join();
406      }
407  
408      /**
409 <     * getQueuedThreads includes waiting threads
409 >     * getQueuedThreads returns all waiting threads
410       */
411 <    public void testGetQueuedThreads() throws InterruptedException {
412 <        final Mutex sync = new Mutex();
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);
269 <        assertTrue(sync.getQueuedThreads().isEmpty());
270 <        t1.join();
271 <        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 {
440 <        final Mutex sync = new Mutex();
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);
297 <        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
298 <        t1.join();
299 <        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 {
468 <        final Mutex sync = new Mutex();
307 <        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
308 <        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
467 >    public void testGetSharedQueuedThreads_Exclusive() {
468 >        final Mutex sync = new Mutex();
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());
324        t1.join();
325        t2.join();
484      }
485  
486      /**
487 <     * tryAcquireNanos is interruptible.
487 >     * getSharedQueuedThreads returns all shared waiting threads
488 >     */
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 testInterruptedException2() throws InterruptedException {
516 <        final Mutex sync = new Mutex();
517 <        sync.acquire(1);
518 <        Thread t = new Thread(new Runnable() {
519 <                public void run() {
520 <                    try {
521 <                        sync.tryAcquireNanos(1, MEDIUM_DELAY_MS * 1000 * 1000);
338 <                        threadShouldThrow();
339 <                    } catch (InterruptedException success) {}
340 <                }
341 <            });
515 >    public void testTryAcquireNanos_Interruptible() {
516 >        final Mutex sync = new Mutex();
517 >        sync.acquire();
518 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
519 >            public void realRun() throws InterruptedException {
520 >                sync.tryAcquireNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
521 >            }});
522  
523 <        t.start();
523 >        waitForQueuedThread(sync, t);
524          t.interrupt();
525 <        t.join();
525 >        awaitTermination(t);
526      }
527  
348
528      /**
529 <     * TryAcquire on exclusively held sync fails
529 >     * tryAcquire on exclusively held sync fails
530       */
531 <    public void testTryAcquireWhenSynced() throws InterruptedException {
532 <        final Mutex sync = new Mutex();
533 <        sync.acquire(1);
534 <        Thread t = new Thread(new Runnable() {
535 <                public void run() {
536 <                    threadAssertFalse(sync.tryAcquire(1));
537 <                }
359 <            });
531 >    public void testTryAcquireWhenSynced() {
532 >        final Mutex sync = new Mutex();
533 >        sync.acquire();
534 >        Thread t = newStartedThread(new CheckedRunnable() {
535 >            public void realRun() {
536 >                assertFalse(sync.tryAcquire());
537 >            }});
538  
539 <        t.start();
540 <        t.join();
363 <        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 {
547 <        final Mutex sync = new Mutex();
548 <        sync.acquire(1);
549 <        Thread t = new Thread(new Runnable() {
550 <                public void run() {
551 <                    try {
552 <                        threadAssertFalse(sync.tryAcquireNanos(1, 1000 * 1000));
553 <                    } catch (Exception ex) {
554 <                        threadUnexpectedException(ex);
555 <                    }
379 <                }
380 <            });
381 <
382 <        t.start();
383 <        t.join();
384 <        sync.release(1);
385 <    }
546 >    public void testAcquireNanos_Timeout() {
547 >        final Mutex sync = new Mutex();
548 >        sync.acquire();
549 >        Thread t = newStartedThread(new CheckedRunnable() {
550 >            public void realRun() throws InterruptedException {
551 >                long startTime = System.nanoTime();
552 >                long nanos = MILLISECONDS.toNanos(timeoutMillis());
553 >                assertFalse(sync.tryAcquireNanos(nanos));
554 >                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
555 >            }});
556  
557 +        awaitTermination(t);
558 +        sync.release();
559 +    }
560  
561      /**
562       * getState is true when acquired and false when not
563       */
564 <    public void testGetState() throws InterruptedException {
565 <        final Mutex sync = new Mutex();
566 <        sync.acquire(1);
394 <        assertTrue(sync.isHeldExclusively());
395 <        sync.release(1);
396 <        assertFalse(sync.isHeldExclusively());
397 <        Thread t = new Thread(new Runnable() {
398 <                public void run() {
399 <                    sync.acquire(1);
400 <                    try {
401 <                        Thread.sleep(SMALL_DELAY_MS);
402 <                    }
403 <                    catch (Exception e) {
404 <                        threadUnexpectedException(e);
405 <                    }
406 <                    sync.release(1);
407 <                }
408 <            });
409 <
410 <        t.start();
411 <        Thread.sleep(SHORT_DELAY_MS);
564 >    public void testGetState() {
565 >        final Mutex sync = new Mutex();
566 >        sync.acquire();
567          assertTrue(sync.isHeldExclusively());
568 <        t.join();
568 >        sync.release();
569          assertFalse(sync.isHeldExclusively());
415    }
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();
576 +                assertTrue(acquired.releaseShared(0));
577 +                done.acquireShared(0);
578 +                sync.release();
579 +            }});
580  
581 <    /**
582 <     * acquireInterruptibly is interruptible.
583 <     */
584 <    public void testAcquireInterruptibly1() throws InterruptedException {
585 <        final Mutex sync = new Mutex();
423 <        sync.acquire(1);
424 <        Thread t = new Thread(new InterruptedSyncRunnable(sync));
425 <        t.start();
426 <        Thread.sleep(SHORT_DELAY_MS);
427 <        t.interrupt();
428 <        Thread.sleep(SHORT_DELAY_MS);
429 <        sync.release(1);
430 <        t.join();
581 >        acquired.acquireShared(0);
582 >        assertTrue(sync.isHeldExclusively());
583 >        assertTrue(done.releaseShared(0));
584 >        awaitTermination(t);
585 >        assertFalse(sync.isHeldExclusively());
586      }
587  
588      /**
589       * acquireInterruptibly succeeds when released, else is interruptible
590       */
591 <    public void testAcquireInterruptibly2() throws InterruptedException {
592 <        final Mutex sync = new Mutex();
593 <        sync.acquireInterruptibly(1);
594 <        Thread t = new Thread(new InterruptedSyncRunnable(sync));
595 <        t.start();
591 >    public void testAcquireInterruptibly() throws InterruptedException {
592 >        final Mutex sync = new Mutex();
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());
443        t.join();
606      }
607  
608      /**
609       * owns is true for a condition created by sync else false
610       */
611      public void testOwns() {
612 <        final Mutex sync = new Mutex();
613 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
612 >        final Mutex sync = new Mutex();
613 >        final ConditionObject c = sync.newCondition();
614          final Mutex sync2 = new Mutex();
615          assertTrue(sync.owns(c));
616          assertFalse(sync2.owns(c));
# Line 457 | Line 619 | public class AbstractQueuedLongSynchroni
619      /**
620       * Calling await without holding sync throws IllegalMonitorStateException
621       */
622 <    public void testAwait_IllegalMonitor() throws InterruptedException {
623 <        final Mutex sync = new Mutex();
624 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
625 <        try {
626 <            c.await();
627 <            shouldThrow();
628 <        }
629 <        catch (IllegalMonitorStateException success) {
622 >    public void testAwait_IMSE() {
623 >        final Mutex sync = new Mutex();
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 {
640 <        final Mutex sync = new Mutex();
641 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
639 >    public void testSignal_IMSE() {
640 >        final Mutex sync = new Mutex();
641 >        final ConditionObject c = sync.newCondition();
642          try {
643              c.signal();
644              shouldThrow();
645 <        }
646 <        catch (IllegalMonitorStateException success) {}
482 <    }
483 <
484 <    /**
485 <     * awaitNanos without a signal times out
486 <     */
487 <    public void testAwaitNanos_Timeout() throws InterruptedException {
488 <        final Mutex sync = new Mutex();
489 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
490 <        sync.acquire(1);
491 <        long t = c.awaitNanos(100);
492 <        assertTrue(t <= 0);
493 <        sync.release(1);
645 >        } catch (IllegalMonitorStateException success) {}
646 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
647      }
648  
649      /**
650 <     *  Timed await without a signal times out
650 >     * Calling signalAll without holding sync throws IllegalMonitorStateException
651       */
652 <    public void testAwait_Timeout() throws InterruptedException {
653 <        final Mutex sync = new Mutex();
654 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
655 <        sync.acquire(1);
656 <        assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
657 <        sync.release(1);
652 >    public void testSignalAll_IMSE() {
653 >        final Mutex sync = new Mutex();
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 {
665 <        final Mutex sync = new Mutex();
666 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
667 <        sync.acquire(1);
668 <        java.util.Date d = new java.util.Date();
669 <        assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
670 <        sync.release(1);
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 ConditionObject c = sync.newCondition();
670 >        sync.acquire();
671 >        assertAwaitTimesOut(c, awaitMethod);
672 >        sync.release();
673      }
674  
675      /**
676 <     * await returns when signalled
677 <     */
678 <    public void testAwait() throws InterruptedException {
679 <        final Mutex sync = new Mutex();
680 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
681 <        Thread t = new Thread(new Runnable() {
682 <                public void run() {
683 <                    try {
684 <                        sync.acquire(1);
685 <                        c.await();
686 <                        sync.release(1);
687 <                    }
688 <                    catch (InterruptedException e) {
689 <                        threadUnexpectedException(e);
690 <                    }
691 <                }
692 <            });
693 <
694 <        t.start();
695 <        Thread.sleep(SHORT_DELAY_MS);
696 <        sync.acquire(1);
676 >     * await/awaitNanos/awaitUntil returns when signalled
677 >     */
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 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();
689 >                assertTrue(acquired.releaseShared(0));
690 >                await(c, awaitMethod);
691 >                sync.release();
692 >            }});
693 >
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  
547
548
705      /**
706 <     * hasWaiters throws NPE if null
706 >     * hasWaiters(null) throws NullPointerException
707       */
708      public void testHasWaitersNPE() {
709 <        final Mutex sync = new Mutex();
709 >        final Mutex sync = new Mutex();
710          try {
711              sync.hasWaiters(null);
712              shouldThrow();
# Line 558 | 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();
720 >        final Mutex sync = new Mutex();
721          try {
722              sync.getWaitQueueLength(null);
723              shouldThrow();
724          } catch (NullPointerException success) {}
725      }
726  
571
727      /**
728       * getWaitingThreads throws NPE if null
729       */
730      public void testGetWaitingThreadsNPE() {
731 <        final Mutex sync = new Mutex();
731 >        final Mutex sync = new Mutex();
732          try {
733              sync.getWaitingThreads(null);
734              shouldThrow();
735          } catch (NullPointerException success) {}
736      }
737  
583
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();
744 <        final Mutex sync2 = new Mutex();
742 >        final Mutex sync = new Mutex();
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();
756 >        final Mutex sync = new Mutex();
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  
609
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();
771 <        final Mutex sync2 = new Mutex();
769 >        final Mutex sync = new Mutex();
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();
783 >        final Mutex sync = new Mutex();
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  
635
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();
798 <        final Mutex sync2 = new Mutex();
796 >        final Mutex sync = new Mutex();
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();
810 >        final Mutex sync = new Mutex();
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  
661
662
819      /**
820       * hasWaiters returns true when a thread is waiting, else false
821       */
822 <    public void testHasWaiters() throws InterruptedException {
823 <        final Mutex sync = new Mutex();
824 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
825 <        Thread t = new Thread(new Runnable() {
826 <                public void run() {
827 <                    try {
828 <                        sync.acquire(1);
829 <                        threadAssertFalse(sync.hasWaiters(c));
830 <                        threadAssertEquals(0, sync.getWaitQueueLength(c));
831 <                        c.await();
832 <                        sync.release(1);
833 <                    }
834 <                    catch (InterruptedException e) {
835 <                        threadUnexpectedException(e);
836 <                    }
837 <                }
838 <            });
839 <
684 <        t.start();
685 <        Thread.sleep(SHORT_DELAY_MS);
686 <        sync.acquire(1);
822 >    public void testHasWaiters() {
823 >        final Mutex sync = new Mutex();
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();
829 >                assertHasWaitersLocked(sync, c, NO_THREADS);
830 >                assertFalse(sync.hasWaiters(c));
831 >                assertTrue(acquired.releaseShared(0));
832 >                c.await();
833 >                sync.release();
834 >            }});
835 >
836 >        acquired.acquireShared(0);
837 >        sync.acquire();
838 >        assertHasWaitersLocked(sync, c, t);
839 >        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
840          assertTrue(sync.hasWaiters(c));
688        assertEquals(1, sync.getWaitQueueLength(c));
841          c.signal();
842 <        sync.release(1);
843 <        Thread.sleep(SHORT_DELAY_MS);
692 <        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 {
855 <        final Mutex sync = new Mutex();
856 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
857 <        Thread t1 = new Thread(new Runnable() {
858 <                public void run() {
859 <                    try {
860 <                        sync.acquire(1);
861 <                        threadAssertFalse(sync.hasWaiters(c));
862 <                        threadAssertEquals(0, sync.getWaitQueueLength(c));
863 <                        c.await();
864 <                        sync.release(1);
865 <                    }
866 <                    catch (InterruptedException e) {
867 <                        threadUnexpectedException(e);
868 <                    }
869 <                }
870 <            });
871 <
872 <        Thread t2 = new Thread(new Runnable() {
722 <                public void run() {
723 <                    try {
724 <                        sync.acquire(1);
725 <                        threadAssertTrue(sync.hasWaiters(c));
726 <                        threadAssertEquals(1, sync.getWaitQueueLength(c));
727 <                        c.await();
728 <                        sync.release(1);
729 <                    }
730 <                    catch (InterruptedException e) {
731 <                        threadUnexpectedException(e);
732 <                    }
733 <                }
734 <            });
854 >    public void testGetWaitQueueLength() {
855 >        final Mutex sync = new Mutex();
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();
862 >                assertHasWaitersLocked(sync, c, NO_THREADS);
863 >                assertEquals(0, sync.getWaitQueueLength(c));
864 >                assertTrue(acquired1.releaseShared(0));
865 >                c.await();
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 <        t1.start();
875 <        Thread.sleep(SHORT_DELAY_MS);
876 <        t2.start();
877 <        Thread.sleep(SHORT_DELAY_MS);
878 <        sync.acquire(1);
879 <        assertTrue(sync.hasWaiters(c));
874 >        final Thread t2 = newStartedThread(new CheckedRunnable() {
875 >            public void realRun() throws InterruptedException {
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();
882 >            }});
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);
746 <        sync.acquire(1);
747 <        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 {
903 <        final Mutex sync = new Mutex();
904 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
905 <        Thread t1 = new Thread(new Runnable() {
906 <                public void run() {
907 <                    try {
908 <                        sync.acquire(1);
909 <                        threadAssertTrue(sync.getWaitingThreads(c).isEmpty());
910 <                        c.await();
911 <                        sync.release(1);
912 <                    }
913 <                    catch (InterruptedException e) {
914 <                        threadUnexpectedException(e);
915 <                    }
916 <                }
917 <            });
918 <
919 <        Thread t2 = new Thread(new Runnable() {
920 <                public void run() {
921 <                    try {
922 <                        sync.acquire(1);
923 <                        threadAssertFalse(sync.getWaitingThreads(c).isEmpty());
924 <                        c.await();
925 <                        sync.release(1);
926 <                    }
927 <                    catch (InterruptedException e) {
928 <                        threadUnexpectedException(e);
929 <                    }
930 <                }
931 <            });
932 <
933 <            sync.acquire(1);
934 <            assertTrue(sync.getWaitingThreads(c).isEmpty());
935 <            sync.release(1);
793 <            t1.start();
794 <            Thread.sleep(SHORT_DELAY_MS);
795 <            t2.start();
796 <            Thread.sleep(SHORT_DELAY_MS);
797 <            sync.acquire(1);
798 <            assertTrue(sync.hasWaiters(c));
799 <            assertTrue(sync.getWaitingThreads(c).contains(t1));
800 <            assertTrue(sync.getWaitingThreads(c).contains(t2));
801 <            c.signalAll();
802 <            sync.release(1);
803 <            Thread.sleep(SHORT_DELAY_MS);
804 <            sync.acquire(1);
805 <            assertFalse(sync.hasWaiters(c));
806 <            assertTrue(sync.getWaitingThreads(c).isEmpty());
807 <            sync.release(1);
808 <            t1.join(SHORT_DELAY_MS);
809 <            t2.join(SHORT_DELAY_MS);
810 <            assertFalse(t1.isAlive());
811 <            assertFalse(t2.isAlive());
812 <    }
902 >    public void testGetWaitingThreads() {
903 >        final Mutex sync = new Mutex();
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();
910 >                assertHasWaitersLocked(sync, c, NO_THREADS);
911 >                assertTrue(sync.getWaitingThreads(c).isEmpty());
912 >                assertTrue(acquired1.releaseShared(0));
913 >                c.await();
914 >                sync.release();
915 >            }});
916 >
917 >        final Thread t2 = new Thread(new CheckedRunnable() {
918 >            public void realRun() throws InterruptedException {
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();
927 >            }});
928 >
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 <    /**
949 <     * awaitUninterruptibly doesn't abort on interrupt
950 <     */
951 <    public void testAwaitUninterruptibly() throws InterruptedException {
952 <        final Mutex sync = new Mutex();
953 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
954 <        Thread t = new Thread(new Runnable() {
955 <                public void run() {
956 <                    sync.acquire(1);
957 <                    c.awaitUninterruptibly();
958 <                    sync.release(1);
959 <                }
960 <            });
961 <
962 <        t.start();
963 <        Thread.sleep(SHORT_DELAY_MS);
964 <        t.interrupt();
965 <        sync.acquire(1);
966 <        c.signal();
967 <        sync.release(1);
836 <        t.join(SHORT_DELAY_MS);
837 <        assertFalse(t.isAlive());
838 <    }
839 <
840 <    /**
841 <     * await is interruptible
842 <     */
843 <    public void testAwait_Interrupt() throws InterruptedException {
844 <        final Mutex sync = new Mutex();
845 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
846 <        Thread t = new Thread(new Runnable() {
847 <                public void run() {
848 <                    try {
849 <                        sync.acquire(1);
850 <                        c.await();
851 <                        sync.release(1);
852 <                        threadShouldThrow();
853 <                    }
854 <                    catch (InterruptedException success) {
855 <                    }
856 <                }
857 <            });
858 <
859 <        t.start();
860 <        Thread.sleep(SHORT_DELAY_MS);
861 <        t.interrupt();
862 <        t.join(SHORT_DELAY_MS);
863 <        assertFalse(t.isAlive());
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 >        awaitTermination(t1);
966 >        awaitTermination(t2);
967 >        assertHasWaitersUnlocked(sync, c, NO_THREADS);
968      }
969  
970      /**
971 <     * awaitNanos is interruptible
972 <     */
973 <    public void testAwaitNanos_Interrupt() throws InterruptedException {
974 <        final Mutex sync = new Mutex();
975 <        final AbstractQueuedLongSynchronizer.ConditionObject c = sync.newCondition();
976 <        Thread t = new Thread(new Runnable() {
977 <                public void run() {
978 <                    try {
979 <                        sync.acquire(1);
980 <                        c.awaitNanos(1000 * 1000 * 1000); // 1 sec
981 <                        sync.release(1);
982 <                        threadShouldThrow();
983 <                    }
984 <                    catch (InterruptedException success) {
985 <                    }
986 <                }
987 <            });
988 <
989 <        t.start();
990 <        Thread.sleep(SHORT_DELAY_MS);
971 >     * awaitUninterruptibly is uninterruptible
972 >     */
973 >    public void testAwaitUninterruptibly() {
974 >        final Mutex sync = new Mutex();
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 >        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 Runnable() {
1011 <                public void run() {
1012 <                    try {
1013 <                        sync.acquire(1);
1014 <                        java.util.Date d = new java.util.Date();
1015 <                        c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1016 <                        sync.release(1);
1017 <                        threadShouldThrow();
1018 <                    }
1019 <                    catch (InterruptedException success) {
1020 <                    }
909 <                }
910 <            });
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();
1018 >                assertTrue(pleaseInterrupt.releaseShared(0));
1019 >                await(c, awaitMethod);
1020 >            }});
1021  
1022 <        t.start();
913 <        Thread.sleep(SHORT_DELAY_MS);
1022 >        pleaseInterrupt.acquireShared(0);
1023          t.interrupt();
1024 <        t.join(SHORT_DELAY_MS);
916 <        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 Runnable() {
1034 <                public void run() {
1035 <                    try {
1036 <                        sync.acquire(1);
1037 <                        c.await();
1038 <                        sync.release(1);
1039 <                    }
1040 <                    catch (InterruptedException e) {
1041 <                        threadUnexpectedException();
1042 <                    }
1043 <                }
1044 <            });
1045 <
1046 <        Thread t2 = new Thread(new Runnable() {
1047 <                public void run() {
1048 <                    try {
1049 <                        sync.acquire(1);
1050 <                        c.await();
1051 <                        sync.release(1);
1052 <                    }
1053 <                    catch (InterruptedException e) {
1054 <                        threadUnexpectedException();
1055 <                    }
1056 <                }
1057 <            });
1058 <
1059 <        t1.start();
952 <        t2.start();
953 <        Thread.sleep(SHORT_DELAY_MS);
954 <        sync.acquire(1);
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();
1042 >                acquired1.releaseShared(0);
1043 >                await(c, awaitMethod);
1044 >                sync.release();
1045 >            }});
1046 >
1047 >        Thread t2 = newStartedThread(new CheckedRunnable() {
1048 >            public void realRun() throws InterruptedException {
1049 >                sync.acquire();
1050 >                acquired2.releaseShared(0);
1051 >                await(c, awaitMethod);
1052 >                sync.release();
1053 >            }});
1054 >
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  
963
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);
972 <        String ls = sync.toString();
973 <        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));
986 <        out.writeObject(l);
987 <        out.close();
988 <
989 <        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
990 <        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
991 <        Mutex r = (Mutex) in.readObject();
992 <        assertTrue(r.isHeldExclusively());
993 <    }
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
1104       */
1105      public void testGetStateWithReleaseShared() {
1106 <        final BooleanLatch l = new BooleanLatch();
1107 <        assertFalse(l.isSignalled());
1108 <        l.releaseShared(0);
1109 <        assertTrue(l.isSignalled());
1106 >        final BooleanLatch l = new BooleanLatch();
1107 >        assertFalse(l.isSignalled());
1108 >        assertTrue(l.releaseShared(0));
1109 >        assertTrue(l.isSignalled());
1110      }
1111  
1112      /**
1113       * releaseShared has no effect when already signalled
1114       */
1115      public void testReleaseShared() {
1116 <        final BooleanLatch l = new BooleanLatch();
1117 <        assertFalse(l.isSignalled());
1118 <        l.releaseShared(0);
1119 <        assertTrue(l.isSignalled());
1120 <        l.releaseShared(0);
1121 <        assertTrue(l.isSignalled());
1116 >        final BooleanLatch l = new BooleanLatch();
1117 >        assertFalse(l.isSignalled());
1118 >        assertTrue(l.releaseShared(0));
1119 >        assertTrue(l.isSignalled());
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 {
1128 <        final BooleanLatch l = new BooleanLatch();
1127 >    public void testAcquireSharedInterruptibly() {
1128 >        final BooleanLatch l = new BooleanLatch();
1129  
1130 <        Thread t = new Thread(new Runnable() {
1131 <                public void run() {
1132 <                    try {
1133 <                        threadAssertFalse(l.isSignalled());
1134 <                        l.acquireSharedInterruptibly(0);
1135 <                        threadAssertTrue(l.isSignalled());
1136 <                    } catch (InterruptedException e) {
1137 <                        threadUnexpectedException();
1032 <                    }
1033 <                }
1034 <            });
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  
1044
1148      /**
1149 <     * acquireSharedTimed returns after release
1149 >     * tryAcquireSharedNanos returns after release, but not before
1150       */
1151 <    public void testAsquireSharedTimed() throws InterruptedException {
1152 <        final BooleanLatch l = new BooleanLatch();
1050 <
1051 <        Thread t = new Thread(new Runnable() {
1052 <                public void run() {
1053 <                    try {
1054 <                        threadAssertFalse(l.isSignalled());
1055 <                        threadAssertTrue(l.tryAcquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
1056 <                        threadAssertTrue(l.isSignalled());
1151 >    public void testTryAcquireSharedNanos() {
1152 >        final BooleanLatch l = new BooleanLatch();
1153  
1154 <                    } catch (InterruptedException e) {
1155 <                        threadUnexpectedException();
1156 <                    }
1157 <                }
1158 <            });
1154 >        Thread t = newStartedThread(new CheckedRunnable() {
1155 >            public void realRun() throws InterruptedException {
1156 >                assertFalse(l.isSignalled());
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() throws InterruptedException {
1175 >    public void testAcquireSharedInterruptibly_Interruptible() {
1176          final BooleanLatch l = new BooleanLatch();
1177 <        Thread t = new Thread(new Runnable() {
1178 <                public void run() {
1179 <                    try {
1180 <                        threadAssertFalse(l.isSignalled());
1181 <                        l.acquireSharedInterruptibly(0);
1082 <                        threadShouldThrow();
1083 <                    } catch (InterruptedException success) {}
1084 <                }
1085 <            });
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 Runnable() {
1196 <                public void run() {
1197 <                    try {
1198 <                        threadAssertFalse(l.isSignalled());
1199 <                        l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
1200 <                        threadShouldThrow();
1104 <                    } catch (InterruptedException success) {}
1105 <                }
1106 <            });
1195 >        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1196 >            public void realRun() throws InterruptedException {
1197 >                assertFalse(l.isSignalled());
1198 >                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
1199 >                l.tryAcquireSharedNanos(0, nanos);
1200 >            }});
1201  
1202 <        t.start();
1109 <        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 Runnable() {
1215 <                public void run() {
1216 <                    try {
1217 <                        threadAssertFalse(l.isSignalled());
1218 <                        threadAssertFalse(l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
1219 <                    } catch (InterruptedException ie) {
1220 <                        threadUnexpectedException();
1221 <                    }
1214 >        final BooleanLatch observedQueued = new BooleanLatch();
1215 >        Thread t = newStartedThread(new CheckedRunnable() {
1216 >            public void realRun() throws InterruptedException {
1217 >                assertFalse(l.isSignalled());
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 <            });
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 >        awaitTermination(t);
1233          assertFalse(l.isSignalled());
1134        t.join();
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