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