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.40 by dl, Fri May 6 16:43:45 2011 UTC vs.
Revision 1.41 by jsr166, Sat May 21 06:24:33 2011 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines