ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.20
Committed: Fri Feb 24 00:03:16 2006 UTC (18 years, 2 months ago) by dl
Branch: MAIN
Changes since 1.19: +1 -0 lines
Log Message:
Make Interruptible locking tests obey delay conventions

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 sync.release(1);
467 t.join();
468 } catch(Exception e){
469 unexpectedException();
470 }
471 }
472
473 /**
474 * acquireInterruptibly succeeds when released, else is interruptible
475 */
476 public void testAcquireInterruptibly2() {
477 final Mutex sync = new Mutex();
478 try {
479 sync.acquireInterruptibly(1);
480 } catch(Exception e) {
481 unexpectedException();
482 }
483 Thread t = new Thread(new InterruptedSyncRunnable(sync));
484 try {
485 t.start();
486 t.interrupt();
487 assertTrue(sync.isHeldExclusively());
488 t.join();
489 } catch(Exception e){
490 unexpectedException();
491 }
492 }
493
494 /**
495 * owns is true for a condition created by sync else false
496 */
497 public void testOwns() {
498 final Mutex sync = new Mutex();
499 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
500 final Mutex sync2 = new Mutex();
501 assertTrue(sync.owns(c));
502 assertFalse(sync2.owns(c));
503 }
504
505 /**
506 * Calling await without holding sync throws IllegalMonitorStateException
507 */
508 public void testAwait_IllegalMonitor() {
509 final Mutex sync = new Mutex();
510 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
511 try {
512 c.await();
513 shouldThrow();
514 }
515 catch (IllegalMonitorStateException success) {
516 }
517 catch (Exception ex) {
518 unexpectedException();
519 }
520 }
521
522 /**
523 * Calling signal without holding sync throws IllegalMonitorStateException
524 */
525 public void testSignal_IllegalMonitor() {
526 final Mutex sync = new Mutex();
527 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
528 try {
529 c.signal();
530 shouldThrow();
531 }
532 catch (IllegalMonitorStateException success) {
533 }
534 catch (Exception ex) {
535 unexpectedException();
536 }
537 }
538
539 /**
540 * awaitNanos without a signal times out
541 */
542 public void testAwaitNanos_Timeout() {
543 final Mutex sync = new Mutex();
544 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
545 try {
546 sync.acquire(1);
547 long t = c.awaitNanos(100);
548 assertTrue(t <= 0);
549 sync.release(1);
550 }
551 catch (Exception ex) {
552 unexpectedException();
553 }
554 }
555
556 /**
557 * Timed await without a signal times out
558 */
559 public void testAwait_Timeout() {
560 final Mutex sync = new Mutex();
561 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
562 try {
563 sync.acquire(1);
564 assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
565 sync.release(1);
566 }
567 catch (Exception ex) {
568 unexpectedException();
569 }
570 }
571
572 /**
573 * awaitUntil without a signal times out
574 */
575 public void testAwaitUntil_Timeout() {
576 final Mutex sync = new Mutex();
577 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
578 try {
579 sync.acquire(1);
580 java.util.Date d = new java.util.Date();
581 assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
582 sync.release(1);
583 }
584 catch (Exception ex) {
585 unexpectedException();
586 }
587 }
588
589 /**
590 * await returns when signalled
591 */
592 public void testAwait() {
593 final Mutex sync = new Mutex();
594 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
595 Thread t = new Thread(new Runnable() {
596 public void run() {
597 try {
598 sync.acquire(1);
599 c.await();
600 sync.release(1);
601 }
602 catch(InterruptedException e) {
603 threadUnexpectedException();
604 }
605 }
606 });
607
608 try {
609 t.start();
610 Thread.sleep(SHORT_DELAY_MS);
611 sync.acquire(1);
612 c.signal();
613 sync.release(1);
614 t.join(SHORT_DELAY_MS);
615 assertFalse(t.isAlive());
616 }
617 catch (Exception ex) {
618 unexpectedException();
619 }
620 }
621
622
623
624 /**
625 * hasWaiters throws NPE if null
626 */
627 public void testHasWaitersNPE() {
628 final Mutex sync = new Mutex();
629 try {
630 sync.hasWaiters(null);
631 shouldThrow();
632 } catch (NullPointerException success) {
633 } catch (Exception ex) {
634 unexpectedException();
635 }
636 }
637
638 /**
639 * getWaitQueueLength throws NPE if null
640 */
641 public void testGetWaitQueueLengthNPE() {
642 final Mutex sync = new Mutex();
643 try {
644 sync.getWaitQueueLength(null);
645 shouldThrow();
646 } catch (NullPointerException success) {
647 } catch (Exception ex) {
648 unexpectedException();
649 }
650 }
651
652
653 /**
654 * getWaitingThreads throws NPE if null
655 */
656 public void testGetWaitingThreadsNPE() {
657 final Mutex sync = new Mutex();
658 try {
659 sync.getWaitingThreads(null);
660 shouldThrow();
661 } catch (NullPointerException success) {
662 } catch (Exception ex) {
663 unexpectedException();
664 }
665 }
666
667
668 /**
669 * hasWaiters throws IAE if not owned
670 */
671 public void testHasWaitersIAE() {
672 final Mutex sync = new Mutex();
673 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
674 final Mutex sync2 = new Mutex();
675 try {
676 sync2.hasWaiters(c);
677 shouldThrow();
678 } catch (IllegalArgumentException success) {
679 } catch (Exception ex) {
680 unexpectedException();
681 }
682 }
683
684 /**
685 * hasWaiters throws IMSE if not synced
686 */
687 public void testHasWaitersIMSE() {
688 final Mutex sync = new Mutex();
689 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
690 try {
691 sync.hasWaiters(c);
692 shouldThrow();
693 } catch (IllegalMonitorStateException success) {
694 } catch (Exception ex) {
695 unexpectedException();
696 }
697 }
698
699
700 /**
701 * getWaitQueueLength throws IAE if not owned
702 */
703 public void testGetWaitQueueLengthIAE() {
704 final Mutex sync = new Mutex();
705 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
706 final Mutex sync2 = new Mutex();
707 try {
708 sync2.getWaitQueueLength(c);
709 shouldThrow();
710 } catch (IllegalArgumentException success) {
711 } catch (Exception ex) {
712 unexpectedException();
713 }
714 }
715
716 /**
717 * getWaitQueueLength throws IMSE if not synced
718 */
719 public void testGetWaitQueueLengthIMSE() {
720 final Mutex sync = new Mutex();
721 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
722 try {
723 sync.getWaitQueueLength(c);
724 shouldThrow();
725 } catch (IllegalMonitorStateException success) {
726 } catch (Exception ex) {
727 unexpectedException();
728 }
729 }
730
731
732 /**
733 * getWaitingThreads throws IAE if not owned
734 */
735 public void testGetWaitingThreadsIAE() {
736 final Mutex sync = new Mutex();
737 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
738 final Mutex sync2 = new Mutex();
739 try {
740 sync2.getWaitingThreads(c);
741 shouldThrow();
742 } catch (IllegalArgumentException success) {
743 } catch (Exception ex) {
744 unexpectedException();
745 }
746 }
747
748 /**
749 * getWaitingThreads throws IMSE if not synced
750 */
751 public void testGetWaitingThreadsIMSE() {
752 final Mutex sync = new Mutex();
753 final AbstractQueuedSynchronizer.ConditionObject c = (sync.newCondition());
754 try {
755 sync.getWaitingThreads(c);
756 shouldThrow();
757 } catch (IllegalMonitorStateException success) {
758 } catch (Exception ex) {
759 unexpectedException();
760 }
761 }
762
763
764
765 /**
766 * hasWaiters returns true when a thread is waiting, else false
767 */
768 public void testHasWaiters() {
769 final Mutex sync = new Mutex();
770 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
771 Thread t = new Thread(new Runnable() {
772 public void run() {
773 try {
774 sync.acquire(1);
775 threadAssertFalse(sync.hasWaiters(c));
776 threadAssertEquals(0, sync.getWaitQueueLength(c));
777 c.await();
778 sync.release(1);
779 }
780 catch(InterruptedException e) {
781 threadUnexpectedException();
782 }
783 }
784 });
785
786 try {
787 t.start();
788 Thread.sleep(SHORT_DELAY_MS);
789 sync.acquire(1);
790 assertTrue(sync.hasWaiters(c));
791 assertEquals(1, sync.getWaitQueueLength(c));
792 c.signal();
793 sync.release(1);
794 Thread.sleep(SHORT_DELAY_MS);
795 sync.acquire(1);
796 assertFalse(sync.hasWaiters(c));
797 assertEquals(0, sync.getWaitQueueLength(c));
798 sync.release(1);
799 t.join(SHORT_DELAY_MS);
800 assertFalse(t.isAlive());
801 }
802 catch (Exception ex) {
803 unexpectedException();
804 }
805 }
806
807 /**
808 * getWaitQueueLength returns number of waiting threads
809 */
810 public void testGetWaitQueueLength() {
811 final Mutex sync = new Mutex();
812 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
813 Thread t1 = new Thread(new Runnable() {
814 public void run() {
815 try {
816 sync.acquire(1);
817 threadAssertFalse(sync.hasWaiters(c));
818 threadAssertEquals(0, sync.getWaitQueueLength(c));
819 c.await();
820 sync.release(1);
821 }
822 catch(InterruptedException e) {
823 threadUnexpectedException();
824 }
825 }
826 });
827
828 Thread t2 = new Thread(new Runnable() {
829 public void run() {
830 try {
831 sync.acquire(1);
832 threadAssertTrue(sync.hasWaiters(c));
833 threadAssertEquals(1, sync.getWaitQueueLength(c));
834 c.await();
835 sync.release(1);
836 }
837 catch(InterruptedException e) {
838 threadUnexpectedException();
839 }
840 }
841 });
842
843 try {
844 t1.start();
845 Thread.sleep(SHORT_DELAY_MS);
846 t2.start();
847 Thread.sleep(SHORT_DELAY_MS);
848 sync.acquire(1);
849 assertTrue(sync.hasWaiters(c));
850 assertEquals(2, sync.getWaitQueueLength(c));
851 c.signalAll();
852 sync.release(1);
853 Thread.sleep(SHORT_DELAY_MS);
854 sync.acquire(1);
855 assertFalse(sync.hasWaiters(c));
856 assertEquals(0, sync.getWaitQueueLength(c));
857 sync.release(1);
858 t1.join(SHORT_DELAY_MS);
859 t2.join(SHORT_DELAY_MS);
860 assertFalse(t1.isAlive());
861 assertFalse(t2.isAlive());
862 }
863 catch (Exception ex) {
864 unexpectedException();
865 }
866 }
867
868 /**
869 * getWaitingThreads returns only and all waiting threads
870 */
871 public void testGetWaitingThreads() {
872 final Mutex sync = new Mutex();
873 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
874 Thread t1 = new Thread(new Runnable() {
875 public void run() {
876 try {
877 sync.acquire(1);
878 threadAssertTrue(sync.getWaitingThreads(c).isEmpty());
879 c.await();
880 sync.release(1);
881 }
882 catch(InterruptedException e) {
883 threadUnexpectedException();
884 }
885 }
886 });
887
888 Thread t2 = new Thread(new Runnable() {
889 public void run() {
890 try {
891 sync.acquire(1);
892 threadAssertFalse(sync.getWaitingThreads(c).isEmpty());
893 c.await();
894 sync.release(1);
895 }
896 catch(InterruptedException e) {
897 threadUnexpectedException();
898 }
899 }
900 });
901
902 try {
903 sync.acquire(1);
904 assertTrue(sync.getWaitingThreads(c).isEmpty());
905 sync.release(1);
906 t1.start();
907 Thread.sleep(SHORT_DELAY_MS);
908 t2.start();
909 Thread.sleep(SHORT_DELAY_MS);
910 sync.acquire(1);
911 assertTrue(sync.hasWaiters(c));
912 assertTrue(sync.getWaitingThreads(c).contains(t1));
913 assertTrue(sync.getWaitingThreads(c).contains(t2));
914 c.signalAll();
915 sync.release(1);
916 Thread.sleep(SHORT_DELAY_MS);
917 sync.acquire(1);
918 assertFalse(sync.hasWaiters(c));
919 assertTrue(sync.getWaitingThreads(c).isEmpty());
920 sync.release(1);
921 t1.join(SHORT_DELAY_MS);
922 t2.join(SHORT_DELAY_MS);
923 assertFalse(t1.isAlive());
924 assertFalse(t2.isAlive());
925 }
926 catch (Exception ex) {
927 unexpectedException();
928 }
929 }
930
931
932
933 /**
934 * awaitUninterruptibly doesn't abort on interrupt
935 */
936 public void testAwaitUninterruptibly() {
937 final Mutex sync = new Mutex();
938 final AbstractQueuedSynchronizer.ConditionObject c = sync.newCondition();
939 Thread t = new Thread(new Runnable() {
940 public void run() {
941 sync.acquire(1);
942 c.awaitUninterruptibly();
943 sync.release(1);
944 }
945 });
946
947 try {
948 t.start();
949 Thread.sleep(SHORT_DELAY_MS);
950 t.interrupt();
951 sync.acquire(1);
952 c.signal();
953 sync.release(1);
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 }