blob: b9dab06adacd410803f1f9ebec78eb4a72eb1eff [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
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
9package jsr166;
10
11import junit.framework.*;
12import java.util.*;
13import static java.util.concurrent.TimeUnit.MILLISECONDS;
14import java.util.concurrent.locks.AbstractQueuedSynchronizer;
15import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject;
16
17public 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
32 @Override public boolean isHeldExclusively() {
33 int state = getState();
34 assertTrue(state == UNLOCKED || state == LOCKED);
35 return state == LOCKED;
36 }
37
38 @Override public boolean tryAcquire(int acquires) {
39 assertEquals(LOCKED, acquires);
40 return compareAndSetState(UNLOCKED, LOCKED);
41 }
42
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
50 public boolean tryAcquireNanos(long nanos) throws InterruptedException {
51 return tryAcquireNanos(LOCKED, nanos);
52 }
53
54 public boolean tryAcquire() {
55 return tryAcquire(LOCKED);
56 }
57
58 public boolean tryRelease() {
59 return tryRelease(LOCKED);
60 }
61
62 public void acquire() {
63 acquire(LOCKED);
64 }
65
66 public void acquireInterruptibly() throws InterruptedException {
67 acquireInterruptibly(LOCKED);
68 }
69
70 public void release() {
71 release(LOCKED);
72 }
73
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 {
83 public boolean isSignalled() { return getState() != 0; }
84
85 public int tryAcquireShared(int ignore) {
86 return isSignalled() ? 1 : -1;
87 }
88
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;
101 InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; }
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;
113 InterruptedSyncRunnable(Mutex sync) { this.sync = sync; }
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
253 public void testIsHeldExclusively() {
254 Mutex sync = new Mutex();
255 assertFalse(sync.isHeldExclusively());
256 }
257
258 /**
259 * acquiring released sync succeeds
260 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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
1205 waitForQueuedThread(l, t);
1206 observedQueued.releaseShared(0);
1207 assertFalse(l.isSignalled());
1208 awaitTermination(t);
1209 assertFalse(l.isSignalled());
1210 }
1211
1212}