ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java
Revision: 1.41
Committed: Mon Jul 17 21:01:30 2017 UTC (6 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.40: +1 -0 lines
Log Message:
suppress [WaitNotInLoop] errorprone warning

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