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

Comparing jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java (file contents):
Revision 1.35 by jsr166, Thu Sep 16 00:52:49 2010 UTC vs.
Revision 1.45 by jsr166, Tue Dec 2 07:23:13 2014 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines