ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.54
Committed: Sun May 14 02:16:56 2017 UTC (6 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.53: +9 -9 lines
Log Message:
improve testAwaitUninterruptibly

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