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.18 by jsr166, Mon Nov 16 05:58:01 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 53 | Line 120 | public class SemaphoreTest extends JSR16
120              s.acquire();
121              s.release();
122              assertEquals(1, s.availablePermits());
123 <        } catch( InterruptedException e){
124 <            fail("unexpected exception");
123 >        } catch (InterruptedException e) {
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 <            fail("unexpected exception");
226 >        } catch (InterruptedException e) {
227 >            unexpectedException();
228          }
229      }
230  
231 <    public void testTimedAcquireReleaseInSameThread(){
232 <        Semaphore s = new Semaphore(1);
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 >            unexpectedException();
572 >        }
573 >    }
574 >
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 117 | Line 589 | public class SemaphoreTest extends JSR16
589              assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
590              s.release();
591              assertEquals(1, s.availablePermits());
592 <        } catch( InterruptedException e){
593 <            fail("unexpected exception");
592 >        } catch (InterruptedException e) {
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();
713 <            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 <            fail("unexpected exception");
718 >        } catch (InterruptedException e) {
719 >            unexpectedException();
720          }
721      }
722  
723 <    public void testAcquire_InterruptedException(){
724 <        final Semaphore s = new Semaphore(0);
725 <        Thread t = new Thread(new Runnable(){
726 <                public void run(){
727 <                    try{
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 >            unexpectedException();
749 >        }
750 >    }
751 >
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 {
767 >            Thread.sleep(SHORT_DELAY_MS);
768 >            t.interrupt();
769 >            t.join();
770 >        } catch (InterruptedException e) {
771 >            unexpectedException();
772 >        }
773 >    }
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{
789 >        try {
790              Thread.sleep(SHORT_DELAY_MS);
791              t.interrupt();
792              t.join();
793 <        } catch(InterruptedException e){
794 <            fail("unexpected exception");
793 >        } catch (InterruptedException e) {
794 >            unexpectedException();
795          }
796      }
797 <    
798 <    public void testTryAcquire_InterruptedException(){
799 <        final Semaphore s = new Semaphore(0);
800 <        Thread t = new Thread(new Runnable(){
801 <                public void run(){
802 <                    try{
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");
817 >        } catch (InterruptedException e) {
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");
897 >        } catch (Exception e) {
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