ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.47
Committed: Wed Dec 31 19:05:42 2014 UTC (9 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.46: +8 -2 lines
Log Message:
no wildcard imports

File Contents

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