ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.21
Committed: Thu May 18 10:29:23 2006 UTC (17 years, 11 months ago) by dl
Branch: MAIN
Changes since 1.20: +1 -0 lines
Log Message:
Add sleeps after interrupts to force ordering

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() {
129 final Mutex sync = new Mutex();
130 Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
131 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
132 try {
133 assertFalse(sync.hasQueuedThreads());
134 sync.acquire(1);
135 t1.start();
136 Thread.sleep(SHORT_DELAY_MS);
137 assertTrue(sync.hasQueuedThreads());
138 t2.start();
139 Thread.sleep(SHORT_DELAY_MS);
140 assertTrue(sync.hasQueuedThreads());
141 t1.interrupt();
142 Thread.sleep(SHORT_DELAY_MS);
143 assertTrue(sync.hasQueuedThreads());
144 sync.release(1);
145 Thread.sleep(SHORT_DELAY_MS);
146 assertFalse(sync.hasQueuedThreads());
147 t1.join();
148 t2.join();
149 } catch(Exception e){
150 unexpectedException();
151 }
152 }
153
154 /**
155 * isQueued(null) throws NPE
156 */
157 public void testIsQueuedNPE() {
158 final Mutex sync = new Mutex();
159 try {
160 sync.isQueued(null);
161 shouldThrow();
162 } catch (NullPointerException success) {
163 }
164 }
165
166 /**
167 * isQueued reports whether a thread is queued.
168 */
169 public void testIsQueued() {
170 final Mutex sync = new Mutex();
171 Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
172 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
173 try {
174 assertFalse(sync.isQueued(t1));
175 assertFalse(sync.isQueued(t2));
176 sync.acquire(1);
177 t1.start();
178 Thread.sleep(SHORT_DELAY_MS);
179 assertTrue(sync.isQueued(t1));
180 t2.start();
181 Thread.sleep(SHORT_DELAY_MS);
182 assertTrue(sync.isQueued(t1));
183 assertTrue(sync.isQueued(t2));
184 t1.interrupt();
185 Thread.sleep(SHORT_DELAY_MS);
186 assertFalse(sync.isQueued(t1));
187 assertTrue(sync.isQueued(t2));
188 sync.release(1);
189 Thread.sleep(SHORT_DELAY_MS);
190 assertFalse(sync.isQueued(t1));
191 Thread.sleep(SHORT_DELAY_MS);
192 assertFalse(sync.isQueued(t2));
193 t1.join();
194 t2.join();
195 } catch(Exception e){
196 unexpectedException();
197 }
198 }
199
200 /**
201 * getFirstQueuedThread returns first waiting thread or null if none
202 */
203 public void testGetFirstQueuedThread() {
204 final Mutex sync = new Mutex();
205 Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
206 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
207 try {
208 assertNull(sync.getFirstQueuedThread());
209 sync.acquire(1);
210 t1.start();
211 Thread.sleep(SHORT_DELAY_MS);
212 assertEquals(t1, sync.getFirstQueuedThread());
213 t2.start();
214 Thread.sleep(SHORT_DELAY_MS);
215 assertEquals(t1, sync.getFirstQueuedThread());
216 t1.interrupt();
217 Thread.sleep(SHORT_DELAY_MS);
218 Thread.sleep(SHORT_DELAY_MS);
219 assertEquals(t2, sync.getFirstQueuedThread());
220 sync.release(1);
221 Thread.sleep(SHORT_DELAY_MS);
222 assertNull(sync.getFirstQueuedThread());
223 t1.join();
224 t2.join();
225 } catch(Exception e){
226 unexpectedException();
227 }
228 }
229
230
231 /**
232 * hasContended reports false if no thread has ever blocked, else true
233 */
234 public void testHasContended() {
235 final Mutex sync = new Mutex();
236 Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
237 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
238 try {
239 assertFalse(sync.hasContended());
240 sync.acquire(1);
241 t1.start();
242 Thread.sleep(SHORT_DELAY_MS);
243 assertTrue(sync.hasContended());
244 t2.start();
245 Thread.sleep(SHORT_DELAY_MS);
246 assertTrue(sync.hasContended());
247 t1.interrupt();
248 Thread.sleep(SHORT_DELAY_MS);
249 assertTrue(sync.hasContended());
250 sync.release(1);
251 Thread.sleep(SHORT_DELAY_MS);
252 assertTrue(sync.hasContended());
253 t1.join();
254 t2.join();
255 } catch(Exception e){
256 unexpectedException();
257 }
258 }
259
260 /**
261 * getQueuedThreads includes waiting threads
262 */
263 public void testGetQueuedThreads() {
264 final Mutex sync = new Mutex();
265 Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
266 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
267 try {
268 assertTrue(sync.getQueuedThreads().isEmpty());
269 sync.acquire(1);
270 assertTrue(sync.getQueuedThreads().isEmpty());
271 t1.start();
272 Thread.sleep(SHORT_DELAY_MS);
273 assertTrue(sync.getQueuedThreads().contains(t1));
274 t2.start();
275 Thread.sleep(SHORT_DELAY_MS);
276 assertTrue(sync.getQueuedThreads().contains(t1));
277 assertTrue(sync.getQueuedThreads().contains(t2));
278 t1.interrupt();
279 Thread.sleep(SHORT_DELAY_MS);
280 assertFalse(sync.getQueuedThreads().contains(t1));
281 assertTrue(sync.getQueuedThreads().contains(t2));
282 sync.release(1);
283 Thread.sleep(SHORT_DELAY_MS);
284 assertTrue(sync.getQueuedThreads().isEmpty());
285 t1.join();
286 t2.join();
287 } catch(Exception e){
288 unexpectedException();
289 }
290 }
291
292 /**
293 * getExclusiveQueuedThreads includes waiting threads
294 */
295 public void testGetExclusiveQueuedThreads() {
296 final Mutex sync = new Mutex();
297 Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
298 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
299 try {
300 assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
301 sync.acquire(1);
302 assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
303 t1.start();
304 Thread.sleep(SHORT_DELAY_MS);
305 assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
306 t2.start();
307 Thread.sleep(SHORT_DELAY_MS);
308 assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
309 assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
310 t1.interrupt();
311 Thread.sleep(SHORT_DELAY_MS);
312 assertFalse(sync.getExclusiveQueuedThreads().contains(t1));
313 assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
314 sync.release(1);
315 Thread.sleep(SHORT_DELAY_MS);
316 assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
317 t1.join();
318 t2.join();
319 } catch(Exception e){
320 unexpectedException();
321 }
322 }
323
324 /**
325 * getSharedQueuedThreads does not include exclusively waiting threads
326 */
327 public void testGetSharedQueuedThreads() {
328 final Mutex sync = new Mutex();
329 Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
330 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
331 try {
332 assertTrue(sync.getSharedQueuedThreads().isEmpty());
333 sync.acquire(1);
334 assertTrue(sync.getSharedQueuedThreads().isEmpty());
335 t1.start();
336 Thread.sleep(SHORT_DELAY_MS);
337 assertTrue(sync.getSharedQueuedThreads().isEmpty());
338 t2.start();
339 Thread.sleep(SHORT_DELAY_MS);
340 assertTrue(sync.getSharedQueuedThreads().isEmpty());
341 t1.interrupt();
342 Thread.sleep(SHORT_DELAY_MS);
343 assertTrue(sync.getSharedQueuedThreads().isEmpty());
344 sync.release(1);
345 Thread.sleep(SHORT_DELAY_MS);
346 assertTrue(sync.getSharedQueuedThreads().isEmpty());
347 t1.join();
348 t2.join();
349 } catch(Exception e){
350 unexpectedException();
351 }
352 }
353
354 /**
355 * tryAcquireNanos is interruptible.
356 */
357 public void testInterruptedException2() {
358 final Mutex sync = new Mutex();
359 sync.acquire(1);
360 Thread t = new Thread(new Runnable() {
361 public void run() {
362 try {
363 sync.tryAcquireNanos(1, MEDIUM_DELAY_MS * 1000 * 1000);
364 threadShouldThrow();
365 } catch(InterruptedException success){}
366 }
367 });
368 try {
369 t.start();
370 t.interrupt();
371 } catch(Exception e){
372 unexpectedException();
373 }
374 }
375
376
377 /**
378 * TryAcquire on exclusively held sync fails
379 */
380 public void testTryAcquireWhenSynced() {
381 final Mutex sync = new Mutex();
382 sync.acquire(1);
383 Thread t = new Thread(new Runnable() {
384 public void run() {
385 threadAssertFalse(sync.tryAcquire(1));
386 }
387 });
388 try {
389 t.start();
390 t.join();
391 sync.release(1);
392 } catch(Exception e){
393 unexpectedException();
394 }
395 }
396
397 /**
398 * tryAcquireNanos on an exclusively held sync times out
399 */
400 public void testAcquireNanos_Timeout() {
401 final Mutex sync = new Mutex();
402 sync.acquire(1);
403 Thread t = new Thread(new Runnable() {
404 public void run() {
405 try {
406 threadAssertFalse(sync.tryAcquireNanos(1, 1000 * 1000));
407 } catch (Exception ex) {
408 threadUnexpectedException();
409 }
410 }
411 });
412 try {
413 t.start();
414 t.join();
415 sync.release(1);
416 } catch(Exception e){
417 unexpectedException();
418 }
419 }
420
421
422 /**
423 * getState is true when acquired and false when not
424 */
425 public void testGetState() {
426 final Mutex sync = new Mutex();
427 sync.acquire(1);
428 assertTrue(sync.isHeldExclusively());
429 sync.release(1);
430 assertFalse(sync.isHeldExclusively());
431 Thread t = new Thread(new Runnable() {
432 public void run() {
433 sync.acquire(1);
434 try {
435 Thread.sleep(SMALL_DELAY_MS);
436 }
437 catch(Exception e) {
438 threadUnexpectedException();
439 }
440 sync.release(1);
441 }
442 });
443 try {
444 t.start();
445 Thread.sleep(SHORT_DELAY_MS);
446 assertTrue(sync.isHeldExclusively());
447 t.join();
448 assertFalse(sync.isHeldExclusively());
449 } catch(Exception e){
450 unexpectedException();
451 }
452 }
453
454
455 /**
456 * acquireInterruptibly is interruptible.
457 */
458 public void testAcquireInterruptibly1() {
459 final Mutex sync = new Mutex();
460 sync.acquire(1);
461 Thread t = new Thread(new InterruptedSyncRunnable(sync));
462 try {
463 t.start();
464 Thread.sleep(SHORT_DELAY_MS);
465 t.interrupt();
466 Thread.sleep(SHORT_DELAY_MS);
467 sync.release(1);
468 t.join();
469 } catch(Exception e){
470 unexpectedException();
471 }
472 }
473
474 /**
475 * acquireInterruptibly succeeds when released, else is interruptible
476 */
477 public void testAcquireInterruptibly2() {
478 final Mutex sync = new Mutex();
479 try {
480 sync.acquireInterruptibly(1);
481 } catch(Exception e) {
482 unexpectedException();
483 }
484 Thread t = new Thread(new InterruptedSyncRunnable(sync));
485 try {
486 t.start();
487 t.interrupt();
488 assertTrue(sync.isHeldExclusively());
489 t.join();
490 } catch(Exception e){
491 unexpectedException();
492 }
493 }
494
495 /**
496 * owns is true for a condition created by sync else false
497 */
498 public void testOwns() {
499 final Mutex sync = new Mutex();
500 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
501 final Mutex sync2 = new Mutex();
502 assertTrue(sync.owns(c));
503 assertFalse(sync2.owns(c));
504 }
505
506 /**
507 * Calling await without holding sync throws IllegalMonitorStateException
508 */
509 public void testAwait_IllegalMonitor() {
510 final Mutex sync = new Mutex();
511 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
512 try {
513 c.await();
514 shouldThrow();
515 }
516 catch (IllegalMonitorStateException success) {
517 }
518 catch (Exception ex) {
519 unexpectedException();
520 }
521 }
522
523 /**
524 * Calling signal without holding sync throws IllegalMonitorStateException
525 */
526 public void testSignal_IllegalMonitor() {
527 final Mutex sync = new Mutex();
528 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
529 try {
530 c.signal();
531 shouldThrow();
532 }
533 catch (IllegalMonitorStateException success) {
534 }
535 catch (Exception ex) {
536 unexpectedException();
537 }
538 }
539
540 /**
541 * awaitNanos without a signal times out
542 */
543 public void testAwaitNanos_Timeout() {
544 final Mutex sync = new Mutex();
545 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
546 try {
547 sync.acquire(1);
548 long t = c.awaitNanos(100);
549 assertTrue(t <= 0);
550 sync.release(1);
551 }
552 catch (Exception ex) {
553 unexpectedException();
554 }
555 }
556
557 /**
558 * Timed await without a signal times out
559 */
560 public void testAwait_Timeout() {
561 final Mutex sync = new Mutex();
562 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
563 try {
564 sync.acquire(1);
565 assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
566 sync.release(1);
567 }
568 catch (Exception ex) {
569 unexpectedException();
570 }
571 }
572
573 /**
574 * awaitUntil without a signal times out
575 */
576 public void testAwaitUntil_Timeout() {
577 final Mutex sync = new Mutex();
578 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
579 try {
580 sync.acquire(1);
581 java.util.Date d = new java.util.Date();
582 assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
583 sync.release(1);
584 }
585 catch (Exception ex) {
586 unexpectedException();
587 }
588 }
589
590 /**
591 * await returns when signalled
592 */
593 public void testAwait() {
594 final Mutex sync = new Mutex();
595 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
596 Thread t = new Thread(new Runnable() {
597 public void run() {
598 try {
599 sync.acquire(1);
600 c.await();
601 sync.release(1);
602 }
603 catch(InterruptedException e) {
604 threadUnexpectedException();
605 }
606 }
607 });
608
609 try {
610 t.start();
611 Thread.sleep(SHORT_DELAY_MS);
612 sync.acquire(1);
613 c.signal();
614 sync.release(1);
615 t.join(SHORT_DELAY_MS);
616 assertFalse(t.isAlive());
617 }
618 catch (Exception ex) {
619 unexpectedException();
620 }
621 }
622
623
624
625 /**
626 * hasWaiters throws NPE if null
627 */
628 public void testHasWaitersNPE() {
629 final Mutex sync = new Mutex();
630 try {
631 sync.hasWaiters(null);
632 shouldThrow();
633 } catch (NullPointerException success) {
634 } catch (Exception ex) {
635 unexpectedException();
636 }
637 }
638
639 /**
640 * getWaitQueueLength throws NPE if null
641 */
642 public void testGetWaitQueueLengthNPE() {
643 final Mutex sync = new Mutex();
644 try {
645 sync.getWaitQueueLength(null);
646 shouldThrow();
647 } catch (NullPointerException success) {
648 } catch (Exception ex) {
649 unexpectedException();
650 }
651 }
652
653
654 /**
655 * getWaitingThreads throws NPE if null
656 */
657 public void testGetWaitingThreadsNPE() {
658 final Mutex sync = new Mutex();
659 try {
660 sync.getWaitingThreads(null);
661 shouldThrow();
662 } catch (NullPointerException success) {
663 } catch (Exception ex) {
664 unexpectedException();
665 }
666 }
667
668
669 /**
670 * hasWaiters throws IAE if not owned
671 */
672 public void testHasWaitersIAE() {
673 final Mutex sync = new Mutex();
674 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
675 final Mutex sync2 = new Mutex();
676 try {
677 sync2.hasWaiters(c);
678 shouldThrow();
679 } catch (IllegalArgumentException success) {
680 } catch (Exception ex) {
681 unexpectedException();
682 }
683 }
684
685 /**
686 * hasWaiters throws IMSE if not synced
687 */
688 public void testHasWaitersIMSE() {
689 final Mutex sync = new Mutex();
690 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
691 try {
692 sync.hasWaiters(c);
693 shouldThrow();
694 } catch (IllegalMonitorStateException success) {
695 } catch (Exception ex) {
696 unexpectedException();
697 }
698 }
699
700
701 /**
702 * getWaitQueueLength throws IAE if not owned
703 */
704 public void testGetWaitQueueLengthIAE() {
705 final Mutex sync = new Mutex();
706 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
707 final Mutex sync2 = new Mutex();
708 try {
709 sync2.getWaitQueueLength(c);
710 shouldThrow();
711 } catch (IllegalArgumentException success) {
712 } catch (Exception ex) {
713 unexpectedException();
714 }
715 }
716
717 /**
718 * getWaitQueueLength throws IMSE if not synced
719 */
720 public void testGetWaitQueueLengthIMSE() {
721 final Mutex sync = new Mutex();
722 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
723 try {
724 sync.getWaitQueueLength(c);
725 shouldThrow();
726 } catch (IllegalMonitorStateException success) {
727 } catch (Exception ex) {
728 unexpectedException();
729 }
730 }
731
732
733 /**
734 * getWaitingThreads throws IAE if not owned
735 */
736 public void testGetWaitingThreadsIAE() {
737 final Mutex sync = new Mutex();
738 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
739 final Mutex sync2 = new Mutex();
740 try {
741 sync2.getWaitingThreads(c);
742 shouldThrow();
743 } catch (IllegalArgumentException success) {
744 } catch (Exception ex) {
745 unexpectedException();
746 }
747 }
748
749 /**
750 * getWaitingThreads throws IMSE if not synced
751 */
752 public void testGetWaitingThreadsIMSE() {
753 final Mutex sync = new Mutex();
754 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
755 try {
756 sync.getWaitingThreads(c);
757 shouldThrow();
758 } catch (IllegalMonitorStateException success) {
759 } catch (Exception ex) {
760 unexpectedException();
761 }
762 }
763
764
765
766 /**
767 * hasWaiters returns true when a thread is waiting, else false
768 */
769 public void testHasWaiters() {
770 final Mutex sync = new Mutex();
771 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
772 Thread t = new Thread(new Runnable() {
773 public void run() {
774 try {
775 sync.acquire(1);
776 threadAssertFalse(sync.hasWaiters(c));
777 threadAssertEquals(0, sync.getWaitQueueLength(c));
778 c.await();
779 sync.release(1);
780 }
781 catch(InterruptedException e) {
782 threadUnexpectedException();
783 }
784 }
785 });
786
787 try {
788 t.start();
789 Thread.sleep(SHORT_DELAY_MS);
790 sync.acquire(1);
791 assertTrue(sync.hasWaiters(c));
792 assertEquals(1, sync.getWaitQueueLength(c));
793 c.signal();
794 sync.release(1);
795 Thread.sleep(SHORT_DELAY_MS);
796 sync.acquire(1);
797 assertFalse(sync.hasWaiters(c));
798 assertEquals(0, sync.getWaitQueueLength(c));
799 sync.release(1);
800 t.join(SHORT_DELAY_MS);
801 assertFalse(t.isAlive());
802 }
803 catch (Exception ex) {
804 unexpectedException();
805 }
806 }
807
808 /**
809 * getWaitQueueLength returns number of waiting threads
810 */
811 public void testGetWaitQueueLength() {
812 final Mutex sync = new Mutex();
813 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
814 Thread t1 = new Thread(new Runnable() {
815 public void run() {
816 try {
817 sync.acquire(1);
818 threadAssertFalse(sync.hasWaiters(c));
819 threadAssertEquals(0, sync.getWaitQueueLength(c));
820 c.await();
821 sync.release(1);
822 }
823 catch(InterruptedException e) {
824 threadUnexpectedException();
825 }
826 }
827 });
828
829 Thread t2 = new Thread(new Runnable() {
830 public void run() {
831 try {
832 sync.acquire(1);
833 threadAssertTrue(sync.hasWaiters(c));
834 threadAssertEquals(1, sync.getWaitQueueLength(c));
835 c.await();
836 sync.release(1);
837 }
838 catch(InterruptedException e) {
839 threadUnexpectedException();
840 }
841 }
842 });
843
844 try {
845 t1.start();
846 Thread.sleep(SHORT_DELAY_MS);
847 t2.start();
848 Thread.sleep(SHORT_DELAY_MS);
849 sync.acquire(1);
850 assertTrue(sync.hasWaiters(c));
851 assertEquals(2, sync.getWaitQueueLength(c));
852 c.signalAll();
853 sync.release(1);
854 Thread.sleep(SHORT_DELAY_MS);
855 sync.acquire(1);
856 assertFalse(sync.hasWaiters(c));
857 assertEquals(0, sync.getWaitQueueLength(c));
858 sync.release(1);
859 t1.join(SHORT_DELAY_MS);
860 t2.join(SHORT_DELAY_MS);
861 assertFalse(t1.isAlive());
862 assertFalse(t2.isAlive());
863 }
864 catch (Exception ex) {
865 unexpectedException();
866 }
867 }
868
869 /**
870 * getWaitingThreads returns only and all waiting threads
871 */
872 public void testGetWaitingThreads() {
873 final Mutex sync = new Mutex();
874 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
875 Thread t1 = new Thread(new Runnable() {
876 public void run() {
877 try {
878 sync.acquire(1);
879 threadAssertTrue(sync.getWaitingThreads(c).isEmpty());
880 c.await();
881 sync.release(1);
882 }
883 catch(InterruptedException e) {
884 threadUnexpectedException();
885 }
886 }
887 });
888
889 Thread t2 = new Thread(new Runnable() {
890 public void run() {
891 try {
892 sync.acquire(1);
893 threadAssertFalse(sync.getWaitingThreads(c).isEmpty());
894 c.await();
895 sync.release(1);
896 }
897 catch(InterruptedException e) {
898 threadUnexpectedException();
899 }
900 }
901 });
902
903 try {
904 sync.acquire(1);
905 assertTrue(sync.getWaitingThreads(c).isEmpty());
906 sync.release(1);
907 t1.start();
908 Thread.sleep(SHORT_DELAY_MS);
909 t2.start();
910 Thread.sleep(SHORT_DELAY_MS);
911 sync.acquire(1);
912 assertTrue(sync.hasWaiters(c));
913 assertTrue(sync.getWaitingThreads(c).contains(t1));
914 assertTrue(sync.getWaitingThreads(c).contains(t2));
915 c.signalAll();
916 sync.release(1);
917 Thread.sleep(SHORT_DELAY_MS);
918 sync.acquire(1);
919 assertFalse(sync.hasWaiters(c));
920 assertTrue(sync.getWaitingThreads(c).isEmpty());
921 sync.release(1);
922 t1.join(SHORT_DELAY_MS);
923 t2.join(SHORT_DELAY_MS);
924 assertFalse(t1.isAlive());
925 assertFalse(t2.isAlive());
926 }
927 catch (Exception ex) {
928 unexpectedException();
929 }
930 }
931
932
933
934 /**
935 * awaitUninterruptibly doesn't abort on interrupt
936 */
937 public void testAwaitUninterruptibly() {
938 final Mutex sync = new Mutex();
939 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
940 Thread t = new Thread(new Runnable() {
941 public void run() {
942 sync.acquire(1);
943 c.awaitUninterruptibly();
944 sync.release(1);
945 }
946 });
947
948 try {
949 t.start();
950 Thread.sleep(SHORT_DELAY_MS);
951 t.interrupt();
952 sync.acquire(1);
953 c.signal();
954 sync.release(1);
955 t.join(SHORT_DELAY_MS);
956 assertFalse(t.isAlive());
957 }
958 catch (Exception ex) {
959 unexpectedException();
960 }
961 }
962
963 /**
964 * await is interruptible
965 */
966 public void testAwait_Interrupt() {
967 final Mutex sync = new Mutex();
968 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
969 Thread t = new Thread(new Runnable() {
970 public void run() {
971 try {
972 sync.acquire(1);
973 c.await();
974 sync.release(1);
975 threadShouldThrow();
976 }
977 catch(InterruptedException success) {
978 }
979 }
980 });
981
982 try {
983 t.start();
984 Thread.sleep(SHORT_DELAY_MS);
985 t.interrupt();
986 t.join(SHORT_DELAY_MS);
987 assertFalse(t.isAlive());
988 }
989 catch (Exception ex) {
990 unexpectedException();
991 }
992 }
993
994 /**
995 * awaitNanos is interruptible
996 */
997 public void testAwaitNanos_Interrupt() {
998 final Mutex sync = new Mutex();
999 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
1000 Thread t = new Thread(new Runnable() {
1001 public void run() {
1002 try {
1003 sync.acquire(1);
1004 c.awaitNanos(1000 * 1000 * 1000); // 1 sec
1005 sync.release(1);
1006 threadShouldThrow();
1007 }
1008 catch(InterruptedException success) {
1009 }
1010 }
1011 });
1012
1013 try {
1014 t.start();
1015 Thread.sleep(SHORT_DELAY_MS);
1016 t.interrupt();
1017 t.join(SHORT_DELAY_MS);
1018 assertFalse(t.isAlive());
1019 }
1020 catch (Exception ex) {
1021 unexpectedException();
1022 }
1023 }
1024
1025 /**
1026 * awaitUntil is interruptible
1027 */
1028 public void testAwaitUntil_Interrupt() {
1029 final Mutex sync = new Mutex();
1030 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
1031 Thread t = new Thread(new Runnable() {
1032 public void run() {
1033 try {
1034 sync.acquire(1);
1035 java.util.Date d = new java.util.Date();
1036 c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1037 sync.release(1);
1038 threadShouldThrow();
1039 }
1040 catch(InterruptedException success) {
1041 }
1042 }
1043 });
1044
1045 try {
1046 t.start();
1047 Thread.sleep(SHORT_DELAY_MS);
1048 t.interrupt();
1049 t.join(SHORT_DELAY_MS);
1050 assertFalse(t.isAlive());
1051 }
1052 catch (Exception ex) {
1053 unexpectedException();
1054 }
1055 }
1056
1057 /**
1058 * signalAll wakes up all threads
1059 */
1060 public void testSignalAll() {
1061 final Mutex sync = new Mutex();
1062 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
1063 Thread t1 = new Thread(new Runnable() {
1064 public void run() {
1065 try {
1066 sync.acquire(1);
1067 c.await();
1068 sync.release(1);
1069 }
1070 catch(InterruptedException e) {
1071 threadUnexpectedException();
1072 }
1073 }
1074 });
1075
1076 Thread t2 = new Thread(new Runnable() {
1077 public void run() {
1078 try {
1079 sync.acquire(1);
1080 c.await();
1081 sync.release(1);
1082 }
1083 catch(InterruptedException e) {
1084 threadUnexpectedException();
1085 }
1086 }
1087 });
1088
1089 try {
1090 t1.start();
1091 t2.start();
1092 Thread.sleep(SHORT_DELAY_MS);
1093 sync.acquire(1);
1094 c.signalAll();
1095 sync.release(1);
1096 t1.join(SHORT_DELAY_MS);
1097 t2.join(SHORT_DELAY_MS);
1098 assertFalse(t1.isAlive());
1099 assertFalse(t2.isAlive());
1100 }
1101 catch (Exception ex) {
1102 unexpectedException();
1103 }
1104 }
1105
1106
1107 /**
1108 * toString indicates current state
1109 */
1110 public void testToString() {
1111 Mutex sync = new Mutex();
1112 String us = sync.toString();
1113 assertTrue(us.indexOf("State = 0") >= 0);
1114 sync.acquire(1);
1115 String ls = sync.toString();
1116 assertTrue(ls.indexOf("State = 1") >= 0);
1117 }
1118
1119 /**
1120 * A serialized AQS deserializes with current state
1121 */
1122 public void testSerialization() {
1123 Mutex l = new Mutex();
1124 l.acquire(1);
1125 assertTrue(l.isHeldExclusively());
1126
1127 try {
1128 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
1129 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
1130 out.writeObject(l);
1131 out.close();
1132
1133 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
1134 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
1135 Mutex r = (Mutex) in.readObject();
1136 assertTrue(r.isHeldExclusively());
1137 } catch(Exception e){
1138 e.printStackTrace();
1139 unexpectedException();
1140 }
1141 }
1142
1143
1144 /**
1145 * tryReleaseShared setting state changes getState
1146 */
1147 public void testGetStateWithReleaseShared() {
1148 final BooleanLatch l = new BooleanLatch();
1149 assertFalse(l.isSignalled());
1150 l.releaseShared(0);
1151 assertTrue(l.isSignalled());
1152 }
1153
1154 /**
1155 * releaseShared has no effect when already signalled
1156 */
1157 public void testReleaseShared() {
1158 final BooleanLatch l = new BooleanLatch();
1159 assertFalse(l.isSignalled());
1160 l.releaseShared(0);
1161 assertTrue(l.isSignalled());
1162 l.releaseShared(0);
1163 assertTrue(l.isSignalled());
1164 }
1165
1166 /**
1167 * acquireSharedInterruptibly returns after release, but not before
1168 */
1169 public void testAcquireSharedInterruptibly() {
1170 final BooleanLatch l = new BooleanLatch();
1171
1172 Thread t = new Thread(new Runnable() {
1173 public void run() {
1174 try {
1175 threadAssertFalse(l.isSignalled());
1176 l.acquireSharedInterruptibly(0);
1177 threadAssertTrue(l.isSignalled());
1178 } catch(InterruptedException e){
1179 threadUnexpectedException();
1180 }
1181 }
1182 });
1183 try {
1184 t.start();
1185 assertFalse(l.isSignalled());
1186 Thread.sleep(SHORT_DELAY_MS);
1187 l.releaseShared(0);
1188 assertTrue(l.isSignalled());
1189 t.join();
1190 } catch (InterruptedException e){
1191 unexpectedException();
1192 }
1193 }
1194
1195
1196 /**
1197 * acquireSharedTimed returns after release
1198 */
1199 public void testAsquireSharedTimed() {
1200 final BooleanLatch l = new BooleanLatch();
1201
1202 Thread t = new Thread(new Runnable() {
1203 public void run() {
1204 try {
1205 threadAssertFalse(l.isSignalled());
1206 threadAssertTrue(l.tryAcquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
1207 threadAssertTrue(l.isSignalled());
1208
1209 } catch(InterruptedException e){
1210 threadUnexpectedException();
1211 }
1212 }
1213 });
1214 try {
1215 t.start();
1216 assertFalse(l.isSignalled());
1217 Thread.sleep(SHORT_DELAY_MS);
1218 l.releaseShared(0);
1219 assertTrue(l.isSignalled());
1220 t.join();
1221 } catch (InterruptedException e){
1222 unexpectedException();
1223 }
1224 }
1225
1226 /**
1227 * acquireSharedInterruptibly throws IE if interrupted before released
1228 */
1229 public void testAcquireSharedInterruptibly_InterruptedException() {
1230 final BooleanLatch l = new BooleanLatch();
1231 Thread t = new Thread(new Runnable() {
1232 public void run() {
1233 try {
1234 threadAssertFalse(l.isSignalled());
1235 l.acquireSharedInterruptibly(0);
1236 threadShouldThrow();
1237 } catch(InterruptedException success){}
1238 }
1239 });
1240 t.start();
1241 try {
1242 assertFalse(l.isSignalled());
1243 t.interrupt();
1244 t.join();
1245 } catch (InterruptedException e){
1246 unexpectedException();
1247 }
1248 }
1249
1250 /**
1251 * acquireSharedTimed throws IE if interrupted before released
1252 */
1253 public void testAcquireSharedNanos_InterruptedException() {
1254 final BooleanLatch l = new BooleanLatch();
1255 Thread t = new Thread(new Runnable() {
1256 public void run() {
1257 try {
1258 threadAssertFalse(l.isSignalled());
1259 l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
1260 threadShouldThrow();
1261 } catch(InterruptedException success){}
1262 }
1263 });
1264 t.start();
1265 try {
1266 Thread.sleep(SHORT_DELAY_MS);
1267 assertFalse(l.isSignalled());
1268 t.interrupt();
1269 t.join();
1270 } catch (InterruptedException e){
1271 unexpectedException();
1272 }
1273 }
1274
1275 /**
1276 * acquireSharedTimed times out if not released before timeout
1277 */
1278 public void testAcquireSharedNanos_Timeout() {
1279 final BooleanLatch l = new BooleanLatch();
1280 Thread t = new Thread(new Runnable() {
1281 public void run() {
1282 try {
1283 threadAssertFalse(l.isSignalled());
1284 threadAssertFalse(l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
1285 } catch(InterruptedException ie){
1286 threadUnexpectedException();
1287 }
1288 }
1289 });
1290 t.start();
1291 try {
1292 Thread.sleep(SHORT_DELAY_MS);
1293 assertFalse(l.isSignalled());
1294 t.join();
1295 } catch (InterruptedException e){
1296 unexpectedException();
1297 }
1298 }
1299
1300
1301 }