ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SemaphoreTest.java
(Generate patch)

Comparing jsr166/src/test/tck/SemaphoreTest.java (file contents):
Revision 1.1 by dl, Sun Aug 31 19:24:55 2003 UTC vs.
Revision 1.6 by dl, Mon Nov 3 13:50:07 2003 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines