ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SemaphoreTest.java
Revision: 1.12
Committed: Sun Jan 4 22:58:03 2004 UTC (20 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.11: +31 -0 lines
Log Message:
Better fairness test

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 import junit.framework.*;
10 import java.util.*;
11 import java.util.concurrent.*;
12 import java.io.*;
13
14 public class SemaphoreTest extends JSR166TestCase {
15 public static void main(String[] args) {
16 junit.textui.TestRunner.run (suite());
17 }
18 public static Test suite() {
19 return new TestSuite(SemaphoreTest.class);
20 }
21
22 /**
23 * Subclass to expose protected methods
24 */
25 static class PublicSemaphore extends Semaphore {
26 PublicSemaphore(int p, boolean f) { super(p, f); }
27 public Collection<Thread> getQueuedThreads() {
28 return super.getQueuedThreads();
29 }
30 public void reducePermits(int p) {
31 super.reducePermits(p);
32 }
33 }
34
35 /**
36 * A runnable calling acquire
37 */
38 class InterruptibleLockRunnable implements Runnable {
39 final Semaphore lock;
40 InterruptibleLockRunnable(Semaphore l) { lock = l; }
41 public void run() {
42 try {
43 lock.acquire();
44 } catch(InterruptedException success){}
45 }
46 }
47
48
49 /**
50 * A runnable calling acquire that expects to be
51 * interrupted
52 */
53 class InterruptedLockRunnable implements Runnable {
54 final Semaphore lock;
55 InterruptedLockRunnable(Semaphore l) { lock = l; }
56 public void run() {
57 try {
58 lock.acquire();
59 threadShouldThrow();
60 } catch(InterruptedException success){}
61 }
62 }
63
64 /**
65 * Zero, negative, and positive initial values are allowed in constructor
66 */
67 public void testConstructor() {
68 Semaphore s0 = new Semaphore(0, false);
69 assertEquals(0, s0.availablePermits());
70 assertFalse(s0.isFair());
71 Semaphore s1 = new Semaphore(-1, false);
72 assertEquals(-1, s1.availablePermits());
73 Semaphore s2 = new Semaphore(-1, false);
74 assertEquals(-1, s2.availablePermits());
75 }
76
77 /**
78 * tryAcquire succeeds when sufficient permits, else fails
79 */
80 public void testTryAcquireInSameThread() {
81 Semaphore s = new Semaphore(2, false);
82 assertEquals(2, s.availablePermits());
83 assertTrue(s.tryAcquire());
84 assertTrue(s.tryAcquire());
85 assertEquals(0, s.availablePermits());
86 assertFalse(s.tryAcquire());
87 }
88
89 /**
90 * Acquire and release of semaphore succeed if initially available
91 */
92 public void testAcquireReleaseInSameThread() {
93 Semaphore s = new Semaphore(1, false);
94 try {
95 s.acquire();
96 s.release();
97 s.acquire();
98 s.release();
99 s.acquire();
100 s.release();
101 s.acquire();
102 s.release();
103 s.acquire();
104 s.release();
105 assertEquals(1, s.availablePermits());
106 } catch( InterruptedException e){
107 unexpectedException();
108 }
109 }
110
111 /**
112 * Uninterruptible acquire and release of semaphore succeed if
113 * initially available
114 */
115 public void testAcquireUninterruptiblyReleaseInSameThread() {
116 Semaphore s = new Semaphore(1, false);
117 try {
118 s.acquireUninterruptibly();
119 s.release();
120 s.acquireUninterruptibly();
121 s.release();
122 s.acquireUninterruptibly();
123 s.release();
124 s.acquireUninterruptibly();
125 s.release();
126 s.acquireUninterruptibly();
127 s.release();
128 assertEquals(1, s.availablePermits());
129 } finally {
130 }
131 }
132
133 /**
134 * Timed Acquire and release of semaphore succeed if
135 * initially available
136 */
137 public void testTimedAcquireReleaseInSameThread() {
138 Semaphore s = new Semaphore(1, false);
139 try {
140 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
141 s.release();
142 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
143 s.release();
144 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
145 s.release();
146 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
147 s.release();
148 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
149 s.release();
150 assertEquals(1, s.availablePermits());
151 } catch( InterruptedException e){
152 unexpectedException();
153 }
154 }
155
156 /**
157 * A release in one thread enables an acquire in another thread
158 */
159 public void testAcquireReleaseInDifferentThreads() {
160 final Semaphore s = new Semaphore(0, false);
161 Thread t = new Thread(new Runnable() {
162 public void run() {
163 try {
164 s.acquire();
165 s.release();
166 s.release();
167 s.acquire();
168 } catch(InterruptedException ie){
169 threadUnexpectedException();
170 }
171 }
172 });
173 try {
174 t.start();
175 Thread.sleep(SHORT_DELAY_MS);
176 s.release();
177 s.release();
178 s.acquire();
179 s.acquire();
180 s.release();
181 t.join();
182 } catch( InterruptedException e){
183 unexpectedException();
184 }
185 }
186
187 /**
188 * A release in one thread enables an uninterruptible acquire in another thread
189 */
190 public void testUninterruptibleAcquireReleaseInDifferentThreads() {
191 final Semaphore s = new Semaphore(0, false);
192 Thread t = new Thread(new Runnable() {
193 public void run() {
194 s.acquireUninterruptibly();
195 s.release();
196 s.release();
197 s.acquireUninterruptibly();
198 }
199 });
200 try {
201 t.start();
202 Thread.sleep(SHORT_DELAY_MS);
203 s.release();
204 s.release();
205 s.acquireUninterruptibly();
206 s.acquireUninterruptibly();
207 s.release();
208 t.join();
209 } catch( InterruptedException e){
210 unexpectedException();
211 }
212 }
213
214
215 /**
216 * A release in one thread enables a timed acquire in another thread
217 */
218 public void testTimedAcquireReleaseInDifferentThreads() {
219 final Semaphore s = new Semaphore(1, false);
220 Thread t = new Thread(new Runnable() {
221 public void run() {
222 try {
223 s.release();
224 threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
225 s.release();
226 threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
227
228 } catch(InterruptedException ie){
229 threadUnexpectedException();
230 }
231 }
232 });
233 try {
234 t.start();
235 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
236 s.release();
237 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
238 s.release();
239 s.release();
240 t.join();
241 } catch( InterruptedException e){
242 unexpectedException();
243 }
244 }
245
246 /**
247 * A waiting acquire blocks interruptibly
248 */
249 public void testAcquire_InterruptedException() {
250 final Semaphore s = new Semaphore(0, false);
251 Thread t = new Thread(new Runnable() {
252 public void run() {
253 try {
254 s.acquire();
255 threadShouldThrow();
256 } catch(InterruptedException success){}
257 }
258 });
259 t.start();
260 try {
261 Thread.sleep(SHORT_DELAY_MS);
262 t.interrupt();
263 t.join();
264 } catch(InterruptedException e){
265 unexpectedException();
266 }
267 }
268
269 /**
270 * A waiting timed acquire blocks interruptibly
271 */
272 public void testTryAcquire_InterruptedException() {
273 final Semaphore s = new Semaphore(0, false);
274 Thread t = new Thread(new Runnable() {
275 public void run() {
276 try {
277 s.tryAcquire(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
278 threadShouldThrow();
279 } catch(InterruptedException success){
280 }
281 }
282 });
283 t.start();
284 try {
285 Thread.sleep(SHORT_DELAY_MS);
286 t.interrupt();
287 t.join();
288 } catch(InterruptedException e){
289 unexpectedException();
290 }
291 }
292
293 /**
294 * hasQueuedThreads reports whether there are waiting threads
295 */
296 public void testHasQueuedThreads() {
297 final Semaphore lock = new Semaphore(1, false);
298 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
299 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
300 try {
301 assertFalse(lock.hasQueuedThreads());
302 lock.acquireUninterruptibly();
303 t1.start();
304 Thread.sleep(SHORT_DELAY_MS);
305 assertTrue(lock.hasQueuedThreads());
306 t2.start();
307 Thread.sleep(SHORT_DELAY_MS);
308 assertTrue(lock.hasQueuedThreads());
309 t1.interrupt();
310 Thread.sleep(SHORT_DELAY_MS);
311 assertTrue(lock.hasQueuedThreads());
312 lock.release();
313 Thread.sleep(SHORT_DELAY_MS);
314 assertFalse(lock.hasQueuedThreads());
315 t1.join();
316 t2.join();
317 } catch(Exception e){
318 unexpectedException();
319 }
320 }
321
322 /**
323 * getQueueLength reports number of waiting threads
324 */
325 public void testGetQueueLength() {
326 final Semaphore lock = new Semaphore(1, false);
327 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
328 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
329 try {
330 assertEquals(0, lock.getQueueLength());
331 lock.acquireUninterruptibly();
332 t1.start();
333 Thread.sleep(SHORT_DELAY_MS);
334 assertEquals(1, lock.getQueueLength());
335 t2.start();
336 Thread.sleep(SHORT_DELAY_MS);
337 assertEquals(2, lock.getQueueLength());
338 t1.interrupt();
339 Thread.sleep(SHORT_DELAY_MS);
340 assertEquals(1, lock.getQueueLength());
341 lock.release();
342 Thread.sleep(SHORT_DELAY_MS);
343 assertEquals(0, lock.getQueueLength());
344 t1.join();
345 t2.join();
346 } catch(Exception e){
347 unexpectedException();
348 }
349 }
350
351 /**
352 * getQueuedThreads includes waiting threads
353 */
354 public void testGetQueuedThreads() {
355 final PublicSemaphore lock = new PublicSemaphore(1, false);
356 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
357 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
358 try {
359 assertTrue(lock.getQueuedThreads().isEmpty());
360 lock.acquireUninterruptibly();
361 assertTrue(lock.getQueuedThreads().isEmpty());
362 t1.start();
363 Thread.sleep(SHORT_DELAY_MS);
364 assertTrue(lock.getQueuedThreads().contains(t1));
365 t2.start();
366 Thread.sleep(SHORT_DELAY_MS);
367 assertTrue(lock.getQueuedThreads().contains(t1));
368 assertTrue(lock.getQueuedThreads().contains(t2));
369 t1.interrupt();
370 Thread.sleep(SHORT_DELAY_MS);
371 assertFalse(lock.getQueuedThreads().contains(t1));
372 assertTrue(lock.getQueuedThreads().contains(t2));
373 lock.release();
374 Thread.sleep(SHORT_DELAY_MS);
375 assertTrue(lock.getQueuedThreads().isEmpty());
376 t1.join();
377 t2.join();
378 } catch(Exception e){
379 unexpectedException();
380 }
381 }
382
383 /**
384 * drainPermits reports and removes given number of permits
385 */
386 public void testDrainPermits() {
387 Semaphore s = new Semaphore(0, false);
388 assertEquals(0, s.availablePermits());
389 assertEquals(0, s.drainPermits());
390 s.release(10);
391 assertEquals(10, s.availablePermits());
392 assertEquals(10, s.drainPermits());
393 assertEquals(0, s.availablePermits());
394 assertEquals(0, s.drainPermits());
395 }
396
397 /**
398 * reducePermits reduces number of permits
399 */
400 public void testReducePermits() {
401 PublicSemaphore s = new PublicSemaphore(10, false);
402 assertEquals(10, s.availablePermits());
403 s.reducePermits(1);
404 assertEquals(9, s.availablePermits());
405 s.reducePermits(10);
406 assertEquals(-1, s.availablePermits());
407 }
408
409 /**
410 * a deserialized serialized semaphore has same number of permits
411 */
412 public void testSerialization() {
413 Semaphore l = new Semaphore(3, false);
414 try {
415 l.acquire();
416 l.release();
417 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
418 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
419 out.writeObject(l);
420 out.close();
421
422 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
423 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
424 Semaphore r = (Semaphore) in.readObject();
425 assertEquals(3, r.availablePermits());
426 assertFalse(r.isFair());
427 r.acquire();
428 r.release();
429 } catch(Exception e){
430 unexpectedException();
431 }
432 }
433
434
435 /**
436 * Zero, negative, and positive initial values are allowed in constructor
437 */
438 public void testConstructor_fair() {
439 Semaphore s0 = new Semaphore(0, true);
440 assertEquals(0, s0.availablePermits());
441 assertTrue(s0.isFair());
442 Semaphore s1 = new Semaphore(-1, true);
443 assertEquals(-1, s1.availablePermits());
444 Semaphore s2 = new Semaphore(-1, true);
445 assertEquals(-1, s2.availablePermits());
446 }
447
448 /**
449 * tryAcquire succeeds when sufficient permits, else fails
450 */
451 public void testTryAcquireInSameThread_fair() {
452 Semaphore s = new Semaphore(2, true);
453 assertEquals(2, s.availablePermits());
454 assertTrue(s.tryAcquire());
455 assertTrue(s.tryAcquire());
456 assertEquals(0, s.availablePermits());
457 assertFalse(s.tryAcquire());
458 }
459
460 /**
461 * tryAcquire(n) succeeds when sufficient permits, else fails
462 */
463 public void testTryAcquireNInSameThread_fair() {
464 Semaphore s = new Semaphore(2, true);
465 assertEquals(2, s.availablePermits());
466 assertTrue(s.tryAcquire(2));
467 assertEquals(0, s.availablePermits());
468 assertFalse(s.tryAcquire());
469 }
470
471 /**
472 * Acquire and release of semaphore succeed if initially available
473 */
474 public void testAcquireReleaseInSameThread_fair() {
475 Semaphore s = new Semaphore(1, true);
476 try {
477 s.acquire();
478 s.release();
479 s.acquire();
480 s.release();
481 s.acquire();
482 s.release();
483 s.acquire();
484 s.release();
485 s.acquire();
486 s.release();
487 assertEquals(1, s.availablePermits());
488 } catch( InterruptedException e){
489 unexpectedException();
490 }
491 }
492
493 /**
494 * Acquire(n) and release(n) of semaphore succeed if initially available
495 */
496 public void testAcquireReleaseNInSameThread_fair() {
497 Semaphore s = new Semaphore(1, true);
498 try {
499 s.release(1);
500 s.acquire(1);
501 s.release(2);
502 s.acquire(2);
503 s.release(3);
504 s.acquire(3);
505 s.release(4);
506 s.acquire(4);
507 s.release(5);
508 s.acquire(5);
509 assertEquals(1, s.availablePermits());
510 } catch( InterruptedException e){
511 unexpectedException();
512 }
513 }
514
515 /**
516 * Acquire(n) and release(n) of semaphore succeed if initially available
517 */
518 public void testAcquireUninterruptiblyReleaseNInSameThread_fair() {
519 Semaphore s = new Semaphore(1, true);
520 try {
521 s.release(1);
522 s.acquireUninterruptibly(1);
523 s.release(2);
524 s.acquireUninterruptibly(2);
525 s.release(3);
526 s.acquireUninterruptibly(3);
527 s.release(4);
528 s.acquireUninterruptibly(4);
529 s.release(5);
530 s.acquireUninterruptibly(5);
531 assertEquals(1, s.availablePermits());
532 } finally {
533 }
534 }
535
536 /**
537 * release(n) in one thread enables timed acquire(n) in another thread
538 */
539 public void testTimedAcquireReleaseNInSameThread_fair() {
540 Semaphore s = new Semaphore(1, true);
541 try {
542 s.release(1);
543 assertTrue(s.tryAcquire(1, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
544 s.release(2);
545 assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
546 s.release(3);
547 assertTrue(s.tryAcquire(3, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
548 s.release(4);
549 assertTrue(s.tryAcquire(4, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
550 s.release(5);
551 assertTrue(s.tryAcquire(5, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
552 assertEquals(1, s.availablePermits());
553 } catch( InterruptedException e){
554 unexpectedException();
555 }
556 }
557
558 /**
559 * release in one thread enables timed acquire in another thread
560 */
561 public void testTimedAcquireReleaseInSameThread_fair() {
562 Semaphore s = new Semaphore(1, true);
563 try {
564 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
565 s.release();
566 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
567 s.release();
568 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
569 s.release();
570 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
571 s.release();
572 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
573 s.release();
574 assertEquals(1, s.availablePermits());
575 } catch( InterruptedException e){
576 unexpectedException();
577 }
578 }
579
580 /**
581 * A release in one thread enables an acquire in another thread
582 */
583 public void testAcquireReleaseInDifferentThreads_fair() {
584 final Semaphore s = new Semaphore(0, true);
585 Thread t = new Thread(new Runnable() {
586 public void run() {
587 try {
588 s.acquire();
589 s.acquire();
590 s.acquire();
591 s.acquire();
592 } catch(InterruptedException ie){
593 threadUnexpectedException();
594 }
595 }
596 });
597 try {
598 t.start();
599 Thread.sleep(SHORT_DELAY_MS);
600 s.release();
601 s.release();
602 s.release();
603 s.release();
604 s.release();
605 s.release();
606 t.join();
607 assertEquals(2, s.availablePermits());
608 } catch( InterruptedException e){
609 unexpectedException();
610 }
611 }
612
613 /**
614 * release(n) in one thread enables acquire(n) in another thread
615 */
616 public void testAcquireReleaseNInDifferentThreads_fair() {
617 final Semaphore s = new Semaphore(0, true);
618 Thread t = new Thread(new Runnable() {
619 public void run() {
620 try {
621 s.acquire();
622 s.release(2);
623 s.acquire();
624 } catch(InterruptedException ie){
625 threadUnexpectedException();
626 }
627 }
628 });
629 try {
630 t.start();
631 Thread.sleep(SHORT_DELAY_MS);
632 s.release(2);
633 s.acquire(2);
634 s.release(1);
635 t.join();
636 } catch( InterruptedException e){
637 unexpectedException();
638 }
639 }
640
641 /**
642 * release(n) in one thread enables acquire(n) in another thread
643 */
644 public void testAcquireReleaseNInDifferentThreads_fair2() {
645 final Semaphore s = new Semaphore(0, true);
646 Thread t = new Thread(new Runnable() {
647 public void run() {
648 try {
649 s.acquire(2);
650 s.acquire(2);
651 s.release(4);
652 } catch(InterruptedException ie){
653 threadUnexpectedException();
654 }
655 }
656 });
657 try {
658 t.start();
659 Thread.sleep(SHORT_DELAY_MS);
660 s.release(6);
661 s.acquire(2);
662 s.acquire(2);
663 s.release(2);
664 t.join();
665 } catch( InterruptedException e){
666 unexpectedException();
667 }
668 }
669
670
671
672
673
674 /**
675 * release in one thread enables timed acquire in another thread
676 */
677 public void testTimedAcquireReleaseInDifferentThreads_fair() {
678 final Semaphore s = new Semaphore(1, true);
679 Thread t = new Thread(new Runnable() {
680 public void run() {
681 try {
682 threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
683 threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
684 threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
685 threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
686 threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
687
688 } catch(InterruptedException ie){
689 threadUnexpectedException();
690 }
691 }
692 });
693 t.start();
694 try {
695 s.release();
696 s.release();
697 s.release();
698 s.release();
699 s.release();
700 t.join();
701 } catch( InterruptedException e){
702 unexpectedException();
703 }
704 }
705
706 /**
707 * release(n) in one thread enables timed acquire(n) in another thread
708 */
709 public void testTimedAcquireReleaseNInDifferentThreads_fair() {
710 final Semaphore s = new Semaphore(2, true);
711 Thread t = new Thread(new Runnable() {
712 public void run() {
713 try {
714 threadAssertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
715 s.release(2);
716 threadAssertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
717 s.release(2);
718 } catch(InterruptedException ie){
719 threadUnexpectedException();
720 }
721 }
722 });
723 t.start();
724 try {
725 assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
726 s.release(2);
727 assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
728 s.release(2);
729 t.join();
730 } catch( InterruptedException e){
731 unexpectedException();
732 }
733 }
734
735 /**
736 * A waiting acquire blocks interruptibly
737 */
738 public void testAcquire_InterruptedException_fair() {
739 final Semaphore s = new Semaphore(0, true);
740 Thread t = new Thread(new Runnable() {
741 public void run() {
742 try {
743 s.acquire();
744 threadShouldThrow();
745 } catch(InterruptedException success){}
746 }
747 });
748 t.start();
749 try {
750 Thread.sleep(SHORT_DELAY_MS);
751 t.interrupt();
752 t.join();
753 } catch(InterruptedException e){
754 unexpectedException();
755 }
756 }
757
758 /**
759 * A waiting acquire(n) blocks interruptibly
760 */
761 public void testAcquireN_InterruptedException_fair() {
762 final Semaphore s = new Semaphore(2, true);
763 Thread t = new Thread(new Runnable() {
764 public void run() {
765 try {
766 s.acquire(3);
767 threadShouldThrow();
768 } catch(InterruptedException success){}
769 }
770 });
771 t.start();
772 try {
773 Thread.sleep(SHORT_DELAY_MS);
774 t.interrupt();
775 t.join();
776 } catch(InterruptedException e){
777 unexpectedException();
778 }
779 }
780
781 /**
782 * A waiting tryAcquire blocks interruptibly
783 */
784 public void testTryAcquire_InterruptedException_fair() {
785 final Semaphore s = new Semaphore(0, true);
786 Thread t = new Thread(new Runnable() {
787 public void run() {
788 try {
789 s.tryAcquire(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
790 threadShouldThrow();
791 } catch(InterruptedException success){
792 }
793 }
794 });
795 t.start();
796 try {
797 Thread.sleep(SHORT_DELAY_MS);
798 t.interrupt();
799 t.join();
800 } catch(InterruptedException e){
801 unexpectedException();
802 }
803 }
804
805 /**
806 * A waiting tryAcquire(n) blocks interruptibly
807 */
808 public void testTryAcquireN_InterruptedException_fair() {
809 final Semaphore s = new Semaphore(1, true);
810 Thread t = new Thread(new Runnable() {
811 public void run() {
812 try {
813 s.tryAcquire(4, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
814 threadShouldThrow();
815 } catch(InterruptedException success){
816 }
817 }
818 });
819 t.start();
820 try {
821 Thread.sleep(SHORT_DELAY_MS);
822 t.interrupt();
823 t.join();
824 } catch(InterruptedException e){
825 unexpectedException();
826 }
827 }
828
829 /**
830 * getQueueLength reports number of waiting threads
831 */
832 public void testGetQueueLength_fair() {
833 final Semaphore lock = new Semaphore(1, true);
834 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
835 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
836 try {
837 assertEquals(0, lock.getQueueLength());
838 lock.acquireUninterruptibly();
839 t1.start();
840 Thread.sleep(SHORT_DELAY_MS);
841 assertEquals(1, lock.getQueueLength());
842 t2.start();
843 Thread.sleep(SHORT_DELAY_MS);
844 assertEquals(2, lock.getQueueLength());
845 t1.interrupt();
846 Thread.sleep(SHORT_DELAY_MS);
847 assertEquals(1, lock.getQueueLength());
848 lock.release();
849 Thread.sleep(SHORT_DELAY_MS);
850 assertEquals(0, lock.getQueueLength());
851 t1.join();
852 t2.join();
853 } catch(Exception e){
854 unexpectedException();
855 }
856 }
857
858
859 /**
860 * a deserialized serialized semaphore has same number of permits
861 */
862 public void testSerialization_fair() {
863 Semaphore l = new Semaphore(3, true);
864
865 try {
866 l.acquire();
867 l.release();
868 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
869 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
870 out.writeObject(l);
871 out.close();
872
873 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
874 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
875 Semaphore r = (Semaphore) in.readObject();
876 assertEquals(3, r.availablePermits());
877 assertTrue(r.isFair());
878 r.acquire();
879 r.release();
880 } catch(Exception e){
881 unexpectedException();
882 }
883 }
884
885
886 }