ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.45
Committed: Tue Dec 2 07:23:13 2014 UTC (9 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.44: +25 -0 lines
Log Message:
add testAwait_Zero testAwait_NegativeInfinity

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