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