ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java
Revision: 1.24
Committed: Sat May 21 06:24:33 2011 UTC (13 years ago) by jsr166
Branch: MAIN
Changes since 1.23: +650 -474 lines
Log Message:
various test improvements

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