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