ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SemaphoreTest.java
Revision: 1.8
Committed: Sun Dec 28 21:56:18 2003 UTC (20 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.7: +29 -0 lines
Log Message:
Add tests for AQS extensions; adjust others for protected condition methods

File Contents

# User Rev Content
1 dl 1.1 /*
2 dl 1.7 * 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 dl 1.1 */
8    
9     import junit.framework.*;
10     import java.util.*;
11     import java.util.concurrent.*;
12 dl 1.2 import java.io.*;
13 dl 1.1
14 dl 1.3 public class SemaphoreTest extends JSR166TestCase {
15 dl 1.1 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 dl 1.4 /**
23 dl 1.6 * 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 dl 1.5 * Zero, negative, and positive initial values are allowed in constructor
66 dl 1.4 */
67 dl 1.5 public void testConstructor() {
68 dl 1.6 Semaphore s0 = new Semaphore(0, false);
69 dl 1.5 assertEquals(0, s0.availablePermits());
70 dl 1.6 assertFalse(s0.isFair());
71     Semaphore s1 = new Semaphore(-1, false);
72 dl 1.5 assertEquals(-1, s1.availablePermits());
73 dl 1.6 Semaphore s2 = new Semaphore(-1, false);
74 dl 1.5 assertEquals(-1, s2.availablePermits());
75 dl 1.1 }
76    
77 dl 1.4 /**
78 dl 1.5 * tryAcquire succeeds when sufficent permits, else fails
79 dl 1.4 */
80 dl 1.1 public void testTryAcquireInSameThread() {
81 dl 1.6 Semaphore s = new Semaphore(2, false);
82 dl 1.1 assertEquals(2, s.availablePermits());
83     assertTrue(s.tryAcquire());
84     assertTrue(s.tryAcquire());
85     assertEquals(0, s.availablePermits());
86     assertFalse(s.tryAcquire());
87     }
88    
89 dl 1.4 /**
90 dl 1.5 * Acquire and release of semaphore succeed if initially available
91 dl 1.4 */
92     public void testAcquireReleaseInSameThread() {
93 dl 1.6 Semaphore s = new Semaphore(1, false);
94 dl 1.1 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 dl 1.4 unexpectedException();
108 dl 1.1 }
109     }
110    
111 dl 1.4 /**
112 dl 1.5 * Uninterruptible acquire and release of semaphore succeed if
113     * initially available
114 dl 1.4 */
115     public void testAcquireUninterruptiblyReleaseInSameThread() {
116 dl 1.6 Semaphore s = new Semaphore(1, false);
117 dl 1.1 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 dl 1.5 /**
134     * Timed Acquire and release of semaphore succeed if
135     * initially available
136     */
137     public void testTimedAcquireReleaseInSameThread() {
138 dl 1.6 Semaphore s = new Semaphore(1, false);
139 dl 1.5 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 dl 1.1
156 dl 1.4 /**
157 dl 1.5 * A release in one thread enables an acquire in another thread
158 dl 1.4 */
159 dl 1.1 public void testAcquireReleaseInDifferentThreads() {
160 dl 1.6 final Semaphore s = new Semaphore(0, false);
161 dl 1.4 Thread t = new Thread(new Runnable() {
162     public void run() {
163     try {
164 dl 1.1 s.acquire();
165     s.release();
166     s.release();
167     s.acquire();
168 dl 1.4 } catch(InterruptedException ie){
169     threadUnexpectedException();
170 dl 1.1 }
171     }
172     });
173     try {
174 dl 1.5 t.start();
175     Thread.sleep(SHORT_DELAY_MS);
176 dl 1.1 s.release();
177     s.release();
178     s.acquire();
179     s.acquire();
180 dl 1.5 s.release();
181 dl 1.1 t.join();
182     } catch( InterruptedException e){
183 dl 1.4 unexpectedException();
184 dl 1.1 }
185     }
186    
187 dl 1.4 /**
188 dl 1.5 * A release in one thread enables an uninterruptible acquire in another thread
189 dl 1.4 */
190 dl 1.5 public void testUninterruptibleAcquireReleaseInDifferentThreads() {
191 dl 1.6 final Semaphore s = new Semaphore(0, false);
192 dl 1.5 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 dl 1.1 try {
201 dl 1.5 t.start();
202     Thread.sleep(SHORT_DELAY_MS);
203 dl 1.1 s.release();
204     s.release();
205 dl 1.5 s.acquireUninterruptibly();
206     s.acquireUninterruptibly();
207 dl 1.1 s.release();
208 dl 1.5 t.join();
209 dl 1.1 } catch( InterruptedException e){
210 dl 1.4 unexpectedException();
211 dl 1.1 }
212     }
213    
214 dl 1.5
215 dl 1.4 /**
216 dl 1.5 * A release in one thread enables a timed acquire in another thread
217 dl 1.4 */
218 dl 1.1 public void testTimedAcquireReleaseInDifferentThreads() {
219 dl 1.6 final Semaphore s = new Semaphore(1, false);
220 dl 1.4 Thread t = new Thread(new Runnable() {
221     public void run() {
222     try {
223 dl 1.1 s.release();
224 dl 1.3 threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
225 dl 1.1 s.release();
226 dl 1.3 threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
227 dl 1.1
228 dl 1.4 } catch(InterruptedException ie){
229     threadUnexpectedException();
230 dl 1.1 }
231     }
232     });
233     try {
234 dl 1.5 t.start();
235 dl 1.1 assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
236     s.release();
237     assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
238     s.release();
239 dl 1.5 s.release();
240 dl 1.1 t.join();
241     } catch( InterruptedException e){
242 dl 1.4 unexpectedException();
243 dl 1.1 }
244     }
245    
246 dl 1.4 /**
247 dl 1.5 * A waiting acquire blocks interruptibly
248 dl 1.4 */
249     public void testAcquire_InterruptedException() {
250 dl 1.6 final Semaphore s = new Semaphore(0, false);
251 dl 1.4 Thread t = new Thread(new Runnable() {
252     public void run() {
253     try {
254 dl 1.1 s.acquire();
255 dl 1.4 threadShouldThrow();
256     } catch(InterruptedException success){}
257 dl 1.1 }
258     });
259     t.start();
260 dl 1.4 try {
261 dl 1.1 Thread.sleep(SHORT_DELAY_MS);
262     t.interrupt();
263     t.join();
264     } catch(InterruptedException e){
265 dl 1.4 unexpectedException();
266 dl 1.1 }
267     }
268    
269 dl 1.4 /**
270 dl 1.5 * A waiting timed acquire blocks interruptibly
271 dl 1.4 */
272     public void testTryAcquire_InterruptedException() {
273 dl 1.6 final Semaphore s = new Semaphore(0, false);
274 dl 1.4 Thread t = new Thread(new Runnable() {
275     public void run() {
276     try {
277 dl 1.1 s.tryAcquire(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
278 dl 1.4 threadShouldThrow();
279     } catch(InterruptedException success){
280 dl 1.1 }
281     }
282     });
283     t.start();
284 dl 1.4 try {
285 dl 1.1 Thread.sleep(SHORT_DELAY_MS);
286     t.interrupt();
287     t.join();
288     } catch(InterruptedException e){
289 dl 1.4 unexpectedException();
290 dl 1.1 }
291     }
292 dl 1.2
293 dl 1.4 /**
294 dl 1.8 * 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 dl 1.6 * 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     /**
385     * reducePermits reduces number of permits
386     */
387     public void testReducePermits() {
388     PublicSemaphore s = new PublicSemaphore(10, false);
389     assertEquals(10, s.availablePermits());
390     s.reducePermits(1);
391     assertEquals(9, s.availablePermits());
392     s.reducePermits(10);
393     assertEquals(-1, s.availablePermits());
394     }
395    
396     /**
397 dl 1.5 * a deserialized serialized semaphore has same number of permits
398 dl 1.4 */
399 dl 1.2 public void testSerialization() {
400 dl 1.6 Semaphore l = new Semaphore(3, false);
401     try {
402     l.acquire();
403     l.release();
404     ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
405     ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
406     out.writeObject(l);
407     out.close();
408    
409     ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
410     ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
411     Semaphore r = (Semaphore) in.readObject();
412     assertEquals(3, r.availablePermits());
413     assertFalse(r.isFair());
414     r.acquire();
415     r.release();
416     } catch(Exception e){
417     unexpectedException();
418     }
419     }
420    
421    
422     /**
423     * Zero, negative, and positive initial values are allowed in constructor
424     */
425     public void testConstructor_fair() {
426     Semaphore s0 = new Semaphore(0, true);
427     assertEquals(0, s0.availablePermits());
428     assertTrue(s0.isFair());
429     Semaphore s1 = new Semaphore(-1, true);
430     assertEquals(-1, s1.availablePermits());
431     Semaphore s2 = new Semaphore(-1, true);
432     assertEquals(-1, s2.availablePermits());
433     }
434    
435     /**
436     * tryAcquire succeeds when sufficent permits, else fails
437     */
438     public void testTryAcquireInSameThread_fair() {
439     Semaphore s = new Semaphore(2, true);
440     assertEquals(2, s.availablePermits());
441     assertTrue(s.tryAcquire());
442     assertTrue(s.tryAcquire());
443     assertEquals(0, s.availablePermits());
444     assertFalse(s.tryAcquire());
445     }
446    
447     /**
448     * tryAcquire(n) succeeds when sufficent permits, else fails
449     */
450     public void testTryAcquireNInSameThread_fair() {
451     Semaphore s = new Semaphore(2, true);
452     assertEquals(2, s.availablePermits());
453     assertTrue(s.tryAcquire(2));
454     assertEquals(0, s.availablePermits());
455     assertFalse(s.tryAcquire());
456     }
457    
458     /**
459     * Acquire and release of semaphore succeed if initially available
460     */
461     public void testAcquireReleaseInSameThread_fair() {
462     Semaphore s = new Semaphore(1, true);
463     try {
464     s.acquire();
465     s.release();
466     s.acquire();
467     s.release();
468     s.acquire();
469     s.release();
470     s.acquire();
471     s.release();
472     s.acquire();
473     s.release();
474     assertEquals(1, s.availablePermits());
475     } catch( InterruptedException e){
476     unexpectedException();
477     }
478     }
479    
480     /**
481     * Acquire(n) and release(n) of semaphore succeed if initially available
482     */
483     public void testAcquireReleaseNInSameThread_fair() {
484     Semaphore s = new Semaphore(1, true);
485     try {
486     s.release(1);
487     s.acquire(1);
488     s.release(2);
489     s.acquire(2);
490     s.release(3);
491     s.acquire(3);
492     s.release(4);
493     s.acquire(4);
494     s.release(5);
495     s.acquire(5);
496     assertEquals(1, s.availablePermits());
497     } catch( InterruptedException e){
498     unexpectedException();
499     }
500     }
501    
502     /**
503     * Acquire(n) and release(n) of semaphore succeed if initially available
504     */
505     public void testAcquireUninterruptiblyReleaseNInSameThread_fair() {
506     Semaphore s = new Semaphore(1, true);
507     try {
508     s.release(1);
509     s.acquireUninterruptibly(1);
510     s.release(2);
511     s.acquireUninterruptibly(2);
512     s.release(3);
513     s.acquireUninterruptibly(3);
514     s.release(4);
515     s.acquireUninterruptibly(4);
516     s.release(5);
517     s.acquireUninterruptibly(5);
518     assertEquals(1, s.availablePermits());
519     } finally {
520     }
521     }
522    
523     /**
524     * release(n) in one thread enables timed acquire(n) in another thread
525     */
526     public void testTimedAcquireReleaseNInSameThread_fair() {
527     Semaphore s = new Semaphore(1, true);
528     try {
529     s.release(1);
530     assertTrue(s.tryAcquire(1, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
531     s.release(2);
532     assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
533     s.release(3);
534     assertTrue(s.tryAcquire(3, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
535     s.release(4);
536     assertTrue(s.tryAcquire(4, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
537     s.release(5);
538     assertTrue(s.tryAcquire(5, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
539     assertEquals(1, s.availablePermits());
540     } catch( InterruptedException e){
541     unexpectedException();
542     }
543     }
544    
545     /**
546     * release in one thread enables timed acquire in another thread
547     */
548     public void testTimedAcquireReleaseInSameThread_fair() {
549     Semaphore s = new Semaphore(1, true);
550     try {
551     assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
552     s.release();
553     assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
554     s.release();
555     assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
556     s.release();
557     assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
558     s.release();
559     assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
560     s.release();
561     assertEquals(1, s.availablePermits());
562     } catch( InterruptedException e){
563     unexpectedException();
564     }
565     }
566    
567     /**
568     * A release in one thread enables an acquire in another thread
569     */
570     public void testAcquireReleaseInDifferentThreads_fair() {
571     final Semaphore s = new Semaphore(0, true);
572     Thread t = new Thread(new Runnable() {
573     public void run() {
574     try {
575     s.acquire();
576     s.acquire();
577     s.acquire();
578     s.acquire();
579     } catch(InterruptedException ie){
580     threadUnexpectedException();
581     }
582     }
583     });
584     try {
585     t.start();
586     Thread.sleep(SHORT_DELAY_MS);
587     s.release();
588     s.release();
589     s.release();
590     s.release();
591     s.release();
592     s.release();
593     t.join();
594     assertEquals(2, s.availablePermits());
595     } catch( InterruptedException e){
596     unexpectedException();
597     }
598     }
599    
600     /**
601     * release(n) in one thread enables acquire(n) in another thread
602     */
603     public void testAcquireReleaseNInDifferentThreads_fair() {
604     final Semaphore s = new Semaphore(0, true);
605     Thread t = new Thread(new Runnable() {
606     public void run() {
607     try {
608     s.acquire(2);
609     s.acquire(2);
610     s.release(4);
611     } catch(InterruptedException ie){
612     threadUnexpectedException();
613     }
614     }
615     });
616     try {
617     t.start();
618     Thread.sleep(SHORT_DELAY_MS);
619     s.release(6);
620     s.acquire(2);
621     s.acquire(2);
622     s.release(2);
623     t.join();
624     } catch( InterruptedException e){
625     unexpectedException();
626     }
627     }
628    
629    
630    
631     /**
632     * release in one thread enables timed acquire in another thread
633     */
634     public void testTimedAcquireReleaseInDifferentThreads_fair() {
635     final Semaphore s = new Semaphore(1, true);
636     Thread t = new Thread(new Runnable() {
637     public void run() {
638     try {
639     threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
640     threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
641     threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
642     threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
643     threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
644    
645     } catch(InterruptedException ie){
646     threadUnexpectedException();
647     }
648     }
649     });
650     t.start();
651     try {
652     s.release();
653     s.release();
654     s.release();
655     s.release();
656     s.release();
657     t.join();
658     } catch( InterruptedException e){
659     unexpectedException();
660     }
661     }
662    
663     /**
664     * release(n) in one thread enables timed acquire(n) in another thread
665     */
666     public void testTimedAcquireReleaseNInDifferentThreads_fair() {
667     final Semaphore s = new Semaphore(2, true);
668     Thread t = new Thread(new Runnable() {
669     public void run() {
670     try {
671     threadAssertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
672     s.release(2);
673     threadAssertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
674     s.release(2);
675     } catch(InterruptedException ie){
676     threadUnexpectedException();
677     }
678     }
679     });
680     t.start();
681     try {
682     assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
683     s.release(2);
684     assertTrue(s.tryAcquire(2, SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
685     s.release(2);
686     t.join();
687     } catch( InterruptedException e){
688     unexpectedException();
689     }
690     }
691    
692     /**
693     * A waiting acquire blocks interruptibly
694     */
695     public void testAcquire_InterruptedException_fair() {
696     final Semaphore s = new Semaphore(0, true);
697     Thread t = new Thread(new Runnable() {
698     public void run() {
699     try {
700     s.acquire();
701     threadShouldThrow();
702     } catch(InterruptedException success){}
703     }
704     });
705     t.start();
706     try {
707     Thread.sleep(SHORT_DELAY_MS);
708     t.interrupt();
709     t.join();
710     } catch(InterruptedException e){
711     unexpectedException();
712     }
713     }
714    
715     /**
716     * A waiting acquire(n) blocks interruptibly
717     */
718     public void testAcquireN_InterruptedException_fair() {
719     final Semaphore s = new Semaphore(2, true);
720     Thread t = new Thread(new Runnable() {
721     public void run() {
722     try {
723     s.acquire(3);
724     threadShouldThrow();
725     } catch(InterruptedException success){}
726     }
727     });
728     t.start();
729     try {
730     Thread.sleep(SHORT_DELAY_MS);
731     t.interrupt();
732     t.join();
733     } catch(InterruptedException e){
734     unexpectedException();
735     }
736     }
737    
738     /**
739     * A waiting tryAcquire blocks interruptibly
740     */
741     public void testTryAcquire_InterruptedException_fair() {
742     final Semaphore s = new Semaphore(0, true);
743     Thread t = new Thread(new Runnable() {
744     public void run() {
745     try {
746     s.tryAcquire(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
747     threadShouldThrow();
748     } catch(InterruptedException success){
749     }
750     }
751     });
752     t.start();
753     try {
754     Thread.sleep(SHORT_DELAY_MS);
755     t.interrupt();
756     t.join();
757     } catch(InterruptedException e){
758     unexpectedException();
759     }
760     }
761    
762     /**
763     * A waiting tryAcquire(n) blocks interruptibly
764     */
765     public void testTryAcquireN_InterruptedException_fair() {
766     final Semaphore s = new Semaphore(1, true);
767     Thread t = new Thread(new Runnable() {
768     public void run() {
769     try {
770     s.tryAcquire(4, MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS);
771     threadShouldThrow();
772     } catch(InterruptedException success){
773     }
774     }
775     });
776     t.start();
777     try {
778     Thread.sleep(SHORT_DELAY_MS);
779     t.interrupt();
780     t.join();
781     } catch(InterruptedException e){
782     unexpectedException();
783     }
784     }
785    
786     /**
787     * getQueueLength reports number of waiting threads
788     */
789     public void testGetQueueLength_fair() {
790     final Semaphore lock = new Semaphore(1, true);
791     Thread t1 = new Thread(new InterruptedLockRunnable(lock));
792     Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
793     try {
794     assertEquals(0, lock.getQueueLength());
795     lock.acquireUninterruptibly();
796     t1.start();
797     Thread.sleep(SHORT_DELAY_MS);
798     assertEquals(1, lock.getQueueLength());
799     t2.start();
800     Thread.sleep(SHORT_DELAY_MS);
801     assertEquals(2, lock.getQueueLength());
802     t1.interrupt();
803     Thread.sleep(SHORT_DELAY_MS);
804     assertEquals(1, lock.getQueueLength());
805     lock.release();
806     Thread.sleep(SHORT_DELAY_MS);
807     assertEquals(0, lock.getQueueLength());
808     t1.join();
809     t2.join();
810     } catch(Exception e){
811     unexpectedException();
812     }
813     }
814    
815    
816     /**
817     * a deserialized serialized semaphore has same number of permits
818     */
819     public void testSerialization_fair() {
820     Semaphore l = new Semaphore(3, true);
821    
822 dl 1.2 try {
823     l.acquire();
824     l.release();
825     ByteArrayOutputStream bout = new ByteArrayOutputStream(10000);
826     ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout));
827     out.writeObject(l);
828     out.close();
829    
830     ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
831     ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin));
832     Semaphore r = (Semaphore) in.readObject();
833     assertEquals(3, r.availablePermits());
834 dl 1.6 assertTrue(r.isFair());
835 dl 1.2 r.acquire();
836     r.release();
837     } catch(Exception e){
838 dl 1.4 unexpectedException();
839 dl 1.2 }
840     }
841 dl 1.6
842 dl 1.2
843 dl 1.1 }