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.2 by dl, Sun Sep 7 20:39:11 2003 UTC vs.
Revision 1.13 by dl, Fri Jan 9 14:45:58 2004 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 10 | Line 11 | import java.util.*;
11   import java.util.concurrent.*;
12   import java.io.*;
13  
14 < public class SemaphoreTest extends TestCase{
14 <
14 > public class SemaphoreTest extends JSR166TestCase {
15      public static void main(String[] args) {
16          junit.textui.TestRunner.run (suite());  
17      }
18    
18      public static Test suite() {
19          return new TestSuite(SemaphoreTest.class);
20      }
21  
22 <    private static long SHORT_DELAY_MS = 100;
23 <    private static long MEDIUM_DELAY_MS = 1000;
24 <    private static long LONG_DELAY_MS = 10000;
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 <    public void testConstructor1() {
49 <        Semaphore s = new Semaphore(0);
50 <        assertEquals(0, s.availablePermits());
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 44 | Line 103 | public class SemaphoreTest extends TestC
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 59 | Line 121 | public class SemaphoreTest extends TestC
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 81 | Line 147 | public class SemaphoreTest extends TestC
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 <                        fail("unexpected exception");
185 >                    } catch(InterruptedException ie){
186 >                        threadUnexpectedException();
187                      }
188                  }
189              });
99        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 <            fail("unexpected exception");
200 >            unexpectedException();
201          }
202      }
203  
204 <    public void testTimedAcquireReleaseInSameThread(){
205 <        Semaphore s = new Semaphore(1);
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 >            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 123 | Line 590 | public class SemaphoreTest extends TestC
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();
603 <                        assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
604 <                        s.release();
605 <                        assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
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 <                    }catch(InterruptedException ie){
688 <                        fail("unexpected exception");
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));
703 >                        threadAssertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
704 >
705 >                    } catch(InterruptedException ie){
706 >                        threadUnexpectedException();
707                      }
708                  }
709              });
710          t.start();
711          try {
147            assertTrue(s.tryAcquire(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
712              s.release();
149            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 <                        fail("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");
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{
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 <                        fail("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();
# Line 210 | Line 891 | public class SemaphoreTest extends TestC
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();
217 <            fail("unexpected exception");
898 >            unexpectedException();
899          }
900      }
901  
902 +
903   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines