ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.18
Committed: Fri Jan 16 16:49:40 2004 UTC (20 years, 3 months ago) by dl
Branch: MAIN
CVS Tags: JSR166_PFD
Changes since 1.17: +2 -0 lines
Log Message:
Fixed timing errors

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 t.interrupt();
465 sync.release(1);
466 t.join();
467 } catch(Exception e){
468 unexpectedException();
469 }
470 }
471
472 /**
473 * acquireInterruptibly succeeds when released, else is interruptible
474 */
475 public void testAcquireInterruptibly2() {
476 final Mutex sync = new Mutex();
477 try {
478 sync.acquireInterruptibly(1);
479 } catch(Exception e) {
480 unexpectedException();
481 }
482 Thread t = new Thread(new InterruptedSyncRunnable(sync));
483 try {
484 t.start();
485 t.interrupt();
486 assertTrue(sync.isHeldExclusively());
487 t.join();
488 } catch(Exception e){
489 unexpectedException();
490 }
491 }
492
493 /**
494 * owns is true for a condition created by sync else false
495 */
496 public void testOwns() {
497 final Mutex sync = new Mutex();
498 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
499 final Mutex sync2 = new Mutex();
500 assertTrue(sync.owns(c));
501 assertFalse(sync2.owns(c));
502 }
503
504 /**
505 * Calling await without holding sync throws IllegalMonitorStateException
506 */
507 public void testAwait_IllegalMonitor() {
508 final Mutex sync = new Mutex();
509 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
510 try {
511 c.await();
512 shouldThrow();
513 }
514 catch (IllegalMonitorStateException success) {
515 }
516 catch (Exception ex) {
517 unexpectedException();
518 }
519 }
520
521 /**
522 * Calling signal without holding sync throws IllegalMonitorStateException
523 */
524 public void testSignal_IllegalMonitor() {
525 final Mutex sync = new Mutex();
526 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
527 try {
528 c.signal();
529 shouldThrow();
530 }
531 catch (IllegalMonitorStateException success) {
532 }
533 catch (Exception ex) {
534 unexpectedException();
535 }
536 }
537
538 /**
539 * awaitNanos without a signal times out
540 */
541 public void testAwaitNanos_Timeout() {
542 final Mutex sync = new Mutex();
543 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
544 try {
545 sync.acquire(1);
546 long t = c.awaitNanos(100);
547 assertTrue(t <= 0);
548 sync.release(1);
549 }
550 catch (Exception ex) {
551 unexpectedException();
552 }
553 }
554
555 /**
556 * Timed await without a signal times out
557 */
558 public void testAwait_Timeout() {
559 final Mutex sync = new Mutex();
560 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
561 try {
562 sync.acquire(1);
563 assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
564 sync.release(1);
565 }
566 catch (Exception ex) {
567 unexpectedException();
568 }
569 }
570
571 /**
572 * awaitUntil without a signal times out
573 */
574 public void testAwaitUntil_Timeout() {
575 final Mutex sync = new Mutex();
576 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
577 try {
578 sync.acquire(1);
579 java.util.Date d = new java.util.Date();
580 assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
581 sync.release(1);
582 }
583 catch (Exception ex) {
584 unexpectedException();
585 }
586 }
587
588 /**
589 * await returns when signalled
590 */
591 public void testAwait() {
592 final Mutex sync = new Mutex();
593 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
594 Thread t = new Thread(new Runnable() {
595 public void run() {
596 try {
597 sync.acquire(1);
598 c.await();
599 sync.release(1);
600 }
601 catch(InterruptedException e) {
602 threadUnexpectedException();
603 }
604 }
605 });
606
607 try {
608 t.start();
609 Thread.sleep(SHORT_DELAY_MS);
610 sync.acquire(1);
611 c.signal();
612 sync.release(1);
613 t.join(SHORT_DELAY_MS);
614 assertFalse(t.isAlive());
615 }
616 catch (Exception ex) {
617 unexpectedException();
618 }
619 }
620
621
622
623 /**
624 * hasWaiters throws NPE if null
625 */
626 public void testHasWaitersNPE() {
627 final Mutex sync = new Mutex();
628 try {
629 sync.hasWaiters(null);
630 shouldThrow();
631 } catch (NullPointerException success) {
632 } catch (Exception ex) {
633 unexpectedException();
634 }
635 }
636
637 /**
638 * getWaitQueueLength throws NPE if null
639 */
640 public void testGetWaitQueueLengthNPE() {
641 final Mutex sync = new Mutex();
642 try {
643 sync.getWaitQueueLength(null);
644 shouldThrow();
645 } catch (NullPointerException success) {
646 } catch (Exception ex) {
647 unexpectedException();
648 }
649 }
650
651
652 /**
653 * getWaitingThreads throws NPE if null
654 */
655 public void testGetWaitingThreadsNPE() {
656 final Mutex sync = new Mutex();
657 try {
658 sync.getWaitingThreads(null);
659 shouldThrow();
660 } catch (NullPointerException success) {
661 } catch (Exception ex) {
662 unexpectedException();
663 }
664 }
665
666
667 /**
668 * hasWaiters throws IAE if not owned
669 */
670 public void testHasWaitersIAE() {
671 final Mutex sync = new Mutex();
672 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
673 final Mutex sync2 = new Mutex();
674 try {
675 sync2.hasWaiters(c);
676 shouldThrow();
677 } catch (IllegalArgumentException success) {
678 } catch (Exception ex) {
679 unexpectedException();
680 }
681 }
682
683 /**
684 * hasWaiters throws IMSE if not synced
685 */
686 public void testHasWaitersIMSE() {
687 final Mutex sync = new Mutex();
688 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
689 try {
690 sync.hasWaiters(c);
691 shouldThrow();
692 } catch (IllegalMonitorStateException success) {
693 } catch (Exception ex) {
694 unexpectedException();
695 }
696 }
697
698
699 /**
700 * getWaitQueueLength throws IAE if not owned
701 */
702 public void testGetWaitQueueLengthIAE() {
703 final Mutex sync = new Mutex();
704 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
705 final Mutex sync2 = new Mutex();
706 try {
707 sync2.getWaitQueueLength(c);
708 shouldThrow();
709 } catch (IllegalArgumentException success) {
710 } catch (Exception ex) {
711 unexpectedException();
712 }
713 }
714
715 /**
716 * getWaitQueueLength throws IMSE if not synced
717 */
718 public void testGetWaitQueueLengthIMSE() {
719 final Mutex sync = new Mutex();
720 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
721 try {
722 sync.getWaitQueueLength(c);
723 shouldThrow();
724 } catch (IllegalMonitorStateException success) {
725 } catch (Exception ex) {
726 unexpectedException();
727 }
728 }
729
730
731 /**
732 * getWaitingThreads throws IAE if not owned
733 */
734 public void testGetWaitingThreadsIAE() {
735 final Mutex sync = new Mutex();
736 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
737 final Mutex sync2 = new Mutex();
738 try {
739 sync2.getWaitingThreads(c);
740 shouldThrow();
741 } catch (IllegalArgumentException success) {
742 } catch (Exception ex) {
743 unexpectedException();
744 }
745 }
746
747 /**
748 * getWaitingThreads throws IMSE if not synced
749 */
750 public void testGetWaitingThreadsIMSE() {
751 final Mutex sync = new Mutex();
752 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
753 try {
754 sync.getWaitingThreads(c);
755 shouldThrow();
756 } catch (IllegalMonitorStateException success) {
757 } catch (Exception ex) {
758 unexpectedException();
759 }
760 }
761
762
763
764 /**
765 * hasWaiters returns true when a thread is waiting, else false
766 */
767 public void testHasWaiters() {
768 final Mutex sync = new Mutex();
769 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
770 Thread t = new Thread(new Runnable() {
771 public void run() {
772 try {
773 sync.acquire(1);
774 threadAssertFalse(sync.hasWaiters(c));
775 threadAssertEquals(0, sync.getWaitQueueLength(c));
776 c.await();
777 sync.release(1);
778 }
779 catch(InterruptedException e) {
780 threadUnexpectedException();
781 }
782 }
783 });
784
785 try {
786 t.start();
787 Thread.sleep(SHORT_DELAY_MS);
788 sync.acquire(1);
789 assertTrue(sync.hasWaiters(c));
790 assertEquals(1, sync.getWaitQueueLength(c));
791 c.signal();
792 sync.release(1);
793 Thread.sleep(SHORT_DELAY_MS);
794 sync.acquire(1);
795 assertFalse(sync.hasWaiters(c));
796 assertEquals(0, sync.getWaitQueueLength(c));
797 sync.release(1);
798 t.join(SHORT_DELAY_MS);
799 assertFalse(t.isAlive());
800 }
801 catch (Exception ex) {
802 unexpectedException();
803 }
804 }
805
806 /**
807 * getWaitQueueLength returns number of waiting threads
808 */
809 public void testGetWaitQueueLength() {
810 final Mutex sync = new Mutex();
811 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
812 Thread t1 = new Thread(new Runnable() {
813 public void run() {
814 try {
815 sync.acquire(1);
816 threadAssertFalse(sync.hasWaiters(c));
817 threadAssertEquals(0, sync.getWaitQueueLength(c));
818 c.await();
819 sync.release(1);
820 }
821 catch(InterruptedException e) {
822 threadUnexpectedException();
823 }
824 }
825 });
826
827 Thread t2 = new Thread(new Runnable() {
828 public void run() {
829 try {
830 sync.acquire(1);
831 threadAssertTrue(sync.hasWaiters(c));
832 threadAssertEquals(1, sync.getWaitQueueLength(c));
833 c.await();
834 sync.release(1);
835 }
836 catch(InterruptedException e) {
837 threadUnexpectedException();
838 }
839 }
840 });
841
842 try {
843 t1.start();
844 Thread.sleep(SHORT_DELAY_MS);
845 t2.start();
846 Thread.sleep(SHORT_DELAY_MS);
847 sync.acquire(1);
848 assertTrue(sync.hasWaiters(c));
849 assertEquals(2, sync.getWaitQueueLength(c));
850 c.signalAll();
851 sync.release(1);
852 Thread.sleep(SHORT_DELAY_MS);
853 sync.acquire(1);
854 assertFalse(sync.hasWaiters(c));
855 assertEquals(0, sync.getWaitQueueLength(c));
856 sync.release(1);
857 t1.join(SHORT_DELAY_MS);
858 t2.join(SHORT_DELAY_MS);
859 assertFalse(t1.isAlive());
860 assertFalse(t2.isAlive());
861 }
862 catch (Exception ex) {
863 unexpectedException();
864 }
865 }
866
867 /**
868 * getWaitingThreads returns only and all waiting threads
869 */
870 public void testGetWaitingThreads() {
871 final Mutex sync = new Mutex();
872 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
873 Thread t1 = new Thread(new Runnable() {
874 public void run() {
875 try {
876 sync.acquire(1);
877 threadAssertTrue(sync.getWaitingThreads(c).isEmpty());
878 c.await();
879 sync.release(1);
880 }
881 catch(InterruptedException e) {
882 threadUnexpectedException();
883 }
884 }
885 });
886
887 Thread t2 = new Thread(new Runnable() {
888 public void run() {
889 try {
890 sync.acquire(1);
891 threadAssertFalse(sync.getWaitingThreads(c).isEmpty());
892 c.await();
893 sync.release(1);
894 }
895 catch(InterruptedException e) {
896 threadUnexpectedException();
897 }
898 }
899 });
900
901 try {
902 sync.acquire(1);
903 assertTrue(sync.getWaitingThreads(c).isEmpty());
904 sync.release(1);
905 t1.start();
906 Thread.sleep(SHORT_DELAY_MS);
907 t2.start();
908 Thread.sleep(SHORT_DELAY_MS);
909 sync.acquire(1);
910 assertTrue(sync.hasWaiters(c));
911 assertTrue(sync.getWaitingThreads(c).contains(t1));
912 assertTrue(sync.getWaitingThreads(c).contains(t2));
913 c.signalAll();
914 sync.release(1);
915 Thread.sleep(SHORT_DELAY_MS);
916 sync.acquire(1);
917 assertFalse(sync.hasWaiters(c));
918 assertTrue(sync.getWaitingThreads(c).isEmpty());
919 sync.release(1);
920 t1.join(SHORT_DELAY_MS);
921 t2.join(SHORT_DELAY_MS);
922 assertFalse(t1.isAlive());
923 assertFalse(t2.isAlive());
924 }
925 catch (Exception ex) {
926 unexpectedException();
927 }
928 }
929
930
931
932 /**
933 * awaitUninterruptibly doesn't abort on interrupt
934 */
935 public void testAwaitUninterruptibly() {
936 final Mutex sync = new Mutex();
937 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
938 Thread t = new Thread(new Runnable() {
939 public void run() {
940 sync.acquire(1);
941 c.awaitUninterruptibly();
942 sync.release(1);
943 }
944 });
945
946 try {
947 t.start();
948 Thread.sleep(SHORT_DELAY_MS);
949 t.interrupt();
950 sync.acquire(1);
951 c.signal();
952 sync.release(1);
953 assert(t.isInterrupted());
954 t.join(SHORT_DELAY_MS);
955 assertFalse(t.isAlive());
956 }
957 catch (Exception ex) {
958 unexpectedException();
959 }
960 }
961
962 /**
963 * await is interruptible
964 */
965 public void testAwait_Interrupt() {
966 final Mutex sync = new Mutex();
967 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
968 Thread t = new Thread(new Runnable() {
969 public void run() {
970 try {
971 sync.acquire(1);
972 c.await();
973 sync.release(1);
974 threadShouldThrow();
975 }
976 catch(InterruptedException success) {
977 }
978 }
979 });
980
981 try {
982 t.start();
983 Thread.sleep(SHORT_DELAY_MS);
984 t.interrupt();
985 t.join(SHORT_DELAY_MS);
986 assertFalse(t.isAlive());
987 }
988 catch (Exception ex) {
989 unexpectedException();
990 }
991 }
992
993 /**
994 * awaitNanos is interruptible
995 */
996 public void testAwaitNanos_Interrupt() {
997 final Mutex sync = new Mutex();
998 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
999 Thread t = new Thread(new Runnable() {
1000 public void run() {
1001 try {
1002 sync.acquire(1);
1003 c.awaitNanos(1000 * 1000 * 1000); // 1 sec
1004 sync.release(1);
1005 threadShouldThrow();
1006 }
1007 catch(InterruptedException success) {
1008 }
1009 }
1010 });
1011
1012 try {
1013 t.start();
1014 Thread.sleep(SHORT_DELAY_MS);
1015 t.interrupt();
1016 t.join(SHORT_DELAY_MS);
1017 assertFalse(t.isAlive());
1018 }
1019 catch (Exception ex) {
1020 unexpectedException();
1021 }
1022 }
1023
1024 /**
1025 * awaitUntil is interruptible
1026 */
1027 public void testAwaitUntil_Interrupt() {
1028 final Mutex sync = new Mutex();
1029 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
1030 Thread t = new Thread(new Runnable() {
1031 public void run() {
1032 try {
1033 sync.acquire(1);
1034 java.util.Date d = new java.util.Date();
1035 c.awaitUntil(new java.util.Date(d.getTime() + 10000));
1036 sync.release(1);
1037 threadShouldThrow();
1038 }
1039 catch(InterruptedException success) {
1040 }
1041 }
1042 });
1043
1044 try {
1045 t.start();
1046 Thread.sleep(SHORT_DELAY_MS);
1047 t.interrupt();
1048 t.join(SHORT_DELAY_MS);
1049 assertFalse(t.isAlive());
1050 }
1051 catch (Exception ex) {
1052 unexpectedException();
1053 }
1054 }
1055
1056 /**
1057 * signalAll wakes up all threads
1058 */
1059 public void testSignalAll() {
1060 final Mutex sync = new Mutex();
1061 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
1062 Thread t1 = new Thread(new Runnable() {
1063 public void run() {
1064 try {
1065 sync.acquire(1);
1066 c.await();
1067 sync.release(1);
1068 }
1069 catch(InterruptedException e) {
1070 threadUnexpectedException();
1071 }
1072 }
1073 });
1074
1075 Thread t2 = new Thread(new Runnable() {
1076 public void run() {
1077 try {
1078 sync.acquire(1);
1079 c.await();
1080 sync.release(1);
1081 }
1082 catch(InterruptedException e) {
1083 threadUnexpectedException();
1084 }
1085 }
1086 });
1087
1088 try {
1089 t1.start();
1090 t2.start();
1091 Thread.sleep(SHORT_DELAY_MS);
1092 sync.acquire(1);
1093 c.signalAll();
1094 sync.release(1);
1095 t1.join(SHORT_DELAY_MS);
1096 t2.join(SHORT_DELAY_MS);
1097 assertFalse(t1.isAlive());
1098 assertFalse(t2.isAlive());
1099 }
1100 catch (Exception ex) {
1101 unexpectedException();
1102 }
1103 }
1104
1105
1106 /**
1107 * toString indicates current state
1108 */
1109 public void testToString() {
1110 Mutex sync = new Mutex();
1111 String us = sync.toString();
1112 assertTrue(us.indexOf("State = 0") >= 0);
1113 sync.acquire(1);
1114 String ls = sync.toString();
1115 assertTrue(ls.indexOf("State = 1") >= 0);
1116 }
1117
1118 /**
1119 * A serialized AQS deserializes with current state
1120 */
1121 public void testSerialization() {
1122 Mutex l = new Mutex();
1123 l.acquire(1);
1124 assertTrue(l.isHeldExclusively());
1125
1126 try {
1127 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
1128 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
1129 out.writeObject(l);
1130 out.close();
1131
1132 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
1133 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
1134 Mutex r = (Mutex) in.readObject();
1135 assertTrue(r.isHeldExclusively());
1136 } catch(Exception e){
1137 e.printStackTrace();
1138 unexpectedException();
1139 }
1140 }
1141
1142
1143 /**
1144 * tryReleaseShared setting state changes getState
1145 */
1146 public void testGetStateWithReleaseShared() {
1147 final BooleanLatch l = new BooleanLatch();
1148 assertFalse(l.isSignalled());
1149 l.releaseShared(0);
1150 assertTrue(l.isSignalled());
1151 }
1152
1153 /**
1154 * releaseShared has no effect when already signalled
1155 */
1156 public void testReleaseShared() {
1157 final BooleanLatch l = new BooleanLatch();
1158 assertFalse(l.isSignalled());
1159 l.releaseShared(0);
1160 assertTrue(l.isSignalled());
1161 l.releaseShared(0);
1162 assertTrue(l.isSignalled());
1163 }
1164
1165 /**
1166 * acquireSharedInterruptibly returns after release, but not before
1167 */
1168 public void testAcquireSharedInterruptibly() {
1169 final BooleanLatch l = new BooleanLatch();
1170
1171 Thread t = new Thread(new Runnable() {
1172 public void run() {
1173 try {
1174 threadAssertFalse(l.isSignalled());
1175 l.acquireSharedInterruptibly(0);
1176 threadAssertTrue(l.isSignalled());
1177 } catch(InterruptedException e){
1178 threadUnexpectedException();
1179 }
1180 }
1181 });
1182 try {
1183 t.start();
1184 assertFalse(l.isSignalled());
1185 Thread.sleep(SHORT_DELAY_MS);
1186 l.releaseShared(0);
1187 assertTrue(l.isSignalled());
1188 t.join();
1189 } catch (InterruptedException e){
1190 unexpectedException();
1191 }
1192 }
1193
1194
1195 /**
1196 * acquireSharedTimed returns after release
1197 */
1198 public void testAsquireSharedTimed() {
1199 final BooleanLatch l = new BooleanLatch();
1200
1201 Thread t = new Thread(new Runnable() {
1202 public void run() {
1203 try {
1204 threadAssertFalse(l.isSignalled());
1205 threadAssertTrue(l.tryAcquireSharedNanos(0, MEDIUM_DELAY_MS* 1000 * 1000));
1206 threadAssertTrue(l.isSignalled());
1207
1208 } catch(InterruptedException e){
1209 threadUnexpectedException();
1210 }
1211 }
1212 });
1213 try {
1214 t.start();
1215 assertFalse(l.isSignalled());
1216 Thread.sleep(SHORT_DELAY_MS);
1217 l.releaseShared(0);
1218 assertTrue(l.isSignalled());
1219 t.join();
1220 } catch (InterruptedException e){
1221 unexpectedException();
1222 }
1223 }
1224
1225 /**
1226 * acquireSharedInterruptibly throws IE if interrupted before released
1227 */
1228 public void testAcquireSharedInterruptibly_InterruptedException() {
1229 final BooleanLatch l = new BooleanLatch();
1230 Thread t = new Thread(new Runnable() {
1231 public void run() {
1232 try {
1233 threadAssertFalse(l.isSignalled());
1234 l.acquireSharedInterruptibly(0);
1235 threadShouldThrow();
1236 } catch(InterruptedException success){}
1237 }
1238 });
1239 t.start();
1240 try {
1241 assertFalse(l.isSignalled());
1242 t.interrupt();
1243 t.join();
1244 } catch (InterruptedException e){
1245 unexpectedException();
1246 }
1247 }
1248
1249 /**
1250 * acquireSharedTimed throws IE if interrupted before released
1251 */
1252 public void testAcquireSharedNanos_InterruptedException() {
1253 final BooleanLatch l = new BooleanLatch();
1254 Thread t = new Thread(new Runnable() {
1255 public void run() {
1256 try {
1257 threadAssertFalse(l.isSignalled());
1258 l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000);
1259 threadShouldThrow();
1260 } catch(InterruptedException success){}
1261 }
1262 });
1263 t.start();
1264 try {
1265 Thread.sleep(SHORT_DELAY_MS);
1266 assertFalse(l.isSignalled());
1267 t.interrupt();
1268 t.join();
1269 } catch (InterruptedException e){
1270 unexpectedException();
1271 }
1272 }
1273
1274 /**
1275 * acquireSharedTimed times out if not released before timeout
1276 */
1277 public void testAcquireSharedNanos_Timeout() {
1278 final BooleanLatch l = new BooleanLatch();
1279 Thread t = new Thread(new Runnable() {
1280 public void run() {
1281 try {
1282 threadAssertFalse(l.isSignalled());
1283 threadAssertFalse(l.tryAcquireSharedNanos(0, SMALL_DELAY_MS* 1000 * 1000));
1284 } catch(InterruptedException ie){
1285 threadUnexpectedException();
1286 }
1287 }
1288 });
1289 t.start();
1290 try {
1291 Thread.sleep(SHORT_DELAY_MS);
1292 assertFalse(l.isSignalled());
1293 t.join();
1294 } catch (InterruptedException e){
1295 unexpectedException();
1296 }
1297 }
1298
1299
1300 }