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