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