ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.42
Committed: Fri Jun 3 05:07:14 2011 UTC (12 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.41: +7 -7 lines
Log Message:
improve "uninterruptible" tests

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