ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java
Revision: 1.30
Committed: Wed Dec 31 19:23:56 2014 UTC (9 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.29: +1 -1 lines
Log Message:
remove stray semicolon

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