ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.26
Committed: Wed Nov 18 08:22:57 2009 UTC (14 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.25: +335 -505 lines
Log Message:
nicer exception handling

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