ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.50
Committed: Sat Apr 25 04:55:30 2015 UTC (9 years ago) by jsr166
Branch: MAIN
Changes since 1.49: +1 -1 lines
Log Message:
improve main methods; respect system properties; actually fail if a test fails

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