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