ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java
Revision: 1.33
Committed: Tue Apr 21 04:48:11 2015 UTC (9 years ago) by jsr166
Branch: MAIN
Changes since 1.32: +1 -1 lines
Log Message:
fix non-sensical 1 << 62 to intended 1L << 62

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