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.3 by dl, Sun Sep 14 20:42:40 2003 UTC vs.
Revision 1.15 by jsr166, Mon Nov 2 20:28:32 2009 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines