ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SemaphoreTest.java
Revision: 1.29
Committed: Tue May 31 16:16:24 2011 UTC (12 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.28: +2 -2 lines
Log Message:
use serialClone in serialization tests; update imports

File Contents

# User Rev Content
1 dl 1.1 /*
2 dl 1.7 * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4 jsr166 1.26 * http://creativecommons.org/publicdomain/zero/1.0/
5 jsr166 1.15 * Other contributors include Andrew Wright, Jeffrey Hayes,
6     * Pat Fisher, Mike Judd.
7 dl 1.1 */
8    
9     import junit.framework.*;
10     import java.util.*;
11 jsr166 1.29 import java.util.concurrent.CountDownLatch;
12     import java.util.concurrent.Semaphore;
13 jsr166 1.19 import static java.util.concurrent.TimeUnit.MILLISECONDS;
14 dl 1.1
15 dl 1.3 public class SemaphoreTest extends JSR166TestCase {
16 dl 1.1 public static void main(String[] args) {
17 jsr166 1.24 junit.textui.TestRunner.run(suite());
18 dl 1.1 }
19     public static Test suite() {
20 jsr166 1.20 return new TestSuite(SemaphoreTest.class);
21 dl 1.1 }
22    
23 dl 1.4 /**
24 dl 1.6 * Subclass to expose protected methods
25     */
26     static class PublicSemaphore extends Semaphore {
27 jsr166 1.28 PublicSemaphore(int permits) { super(permits); }
28     PublicSemaphore(int permits, boolean fair) { super(permits, fair); }
29 jsr166 1.15 public Collection<Thread> getQueuedThreads() {
30     return super.getQueuedThreads();
31 dl 1.6 }
32 jsr166 1.28 public boolean hasQueuedThread(Thread t) {
33     return super.getQueuedThreads().contains(t);
34     }
35     public void reducePermits(int reduction) {
36     super.reducePermits(reduction);
37 dl 1.6 }
38     }
39    
40     /**
41     * A runnable calling acquire
42     */
43 jsr166 1.19 class InterruptibleLockRunnable extends CheckedRunnable {
44 dl 1.6 final Semaphore lock;
45 jsr166 1.28 InterruptibleLockRunnable(Semaphore s) { lock = s; }
46 jsr166 1.19 public void realRun() {
47 dl 1.6 try {
48     lock.acquire();
49 jsr166 1.19 }
50     catch (InterruptedException ignored) {}
51 dl 1.6 }
52     }
53    
54     /**
55 jsr166 1.21 * A runnable calling acquire that expects to be interrupted
56 dl 1.6 */
57 jsr166 1.19 class InterruptedLockRunnable extends CheckedInterruptedRunnable {
58 dl 1.6 final Semaphore lock;
59 jsr166 1.28 InterruptedLockRunnable(Semaphore s) { lock = s; }
60 jsr166 1.19 public void realRun() throws InterruptedException {
61     lock.acquire();
62 dl 1.6 }
63     }
64    
65     /**
66 jsr166 1.28 * Spin-waits until s.hasQueuedThread(t) becomes true.
67     */
68     void waitForQueuedThread(PublicSemaphore s, Thread t) {
69     long startTime = System.nanoTime();
70     while (!s.hasQueuedThread(t)) {
71     if (millisElapsedSince(startTime) > LONG_DELAY_MS)
72     throw new AssertionFailedError("timed out");
73     Thread.yield();
74     }
75     assert(s.hasQueuedThreads());
76     assertTrue(t.isAlive());
77     }
78    
79     /**
80     * Spin-waits until s.hasQueuedThreads() becomes true.
81     */
82     void waitForQueuedThreads(Semaphore s) {
83     long startTime = System.nanoTime();
84     while (!s.hasQueuedThreads()) {
85     if (millisElapsedSince(startTime) > LONG_DELAY_MS)
86     throw new AssertionFailedError("timed out");
87     Thread.yield();
88     }
89     }
90    
91     enum AcquireMethod {
92     acquire() {
93     void acquire(Semaphore s) throws InterruptedException {
94     s.acquire();
95     }
96     },
97     acquireN() {
98     void acquire(Semaphore s, int permits) throws InterruptedException {
99     s.acquire(permits);
100     }
101     },
102     acquireUninterruptibly() {
103     void acquire(Semaphore s) {
104     s.acquireUninterruptibly();
105     }
106     },
107     acquireUninterruptiblyN() {
108     void acquire(Semaphore s, int permits) {
109     s.acquireUninterruptibly(permits);
110     }
111     },
112     tryAcquire() {
113     void acquire(Semaphore s) {
114     assertTrue(s.tryAcquire());
115     }
116     },
117     tryAcquireN() {
118     void acquire(Semaphore s, int permits) {
119     assertTrue(s.tryAcquire(permits));
120     }
121     },
122     tryAcquireTimed() {
123     void acquire(Semaphore s) throws InterruptedException {
124     assertTrue(s.tryAcquire(2 * LONG_DELAY_MS, MILLISECONDS));
125     }
126     },
127     tryAcquireTimedN {
128     void acquire(Semaphore s, int permits) throws InterruptedException {
129     assertTrue(s.tryAcquire(permits, 2 * LONG_DELAY_MS, MILLISECONDS));
130     }
131     };
132    
133     // Intentionally meta-circular
134    
135     /** Acquires 1 permit. */
136     void acquire(Semaphore s) throws InterruptedException {
137     acquire(s, 1);
138     }
139     /** Acquires the given number of permits. */
140     void acquire(Semaphore s, int permits) throws InterruptedException {
141     for (int i = 0; i < permits; i++)
142     acquire(s);
143     }
144     }
145    
146     /**
147 dl 1.5 * Zero, negative, and positive initial values are allowed in constructor
148 dl 1.4 */
149 jsr166 1.28 public void testConstructor() { testConstructor(false); }
150     public void testConstructor_fair() { testConstructor(true); }
151     public void testConstructor(boolean fair) {
152     for (int permits : new int[] { -42, -1, 0, 1, 42 }) {
153     Semaphore s = new Semaphore(permits, fair);
154     assertEquals(permits, s.availablePermits());
155     assertEquals(fair, s.isFair());
156 jsr166 1.19 }
157 dl 1.13 }
158    
159     /**
160     * Constructor without fairness argument behaves as nonfair
161     */
162 jsr166 1.28 public void testConstructorDefaultsToNonFair() {
163     for (int permits : new int[] { -42, -1, 0, 1, 42 }) {
164 jsr166 1.19 Semaphore s = new Semaphore(permits);
165     assertEquals(permits, s.availablePermits());
166     assertFalse(s.isFair());
167     }
168 dl 1.1 }
169    
170 dl 1.4 /**
171 dl 1.9 * tryAcquire succeeds when sufficient permits, else fails
172 dl 1.4 */
173 jsr166 1.28 public void testTryAcquireInSameThread() { testTryAcquireInSameThread(false); }
174     public void testTryAcquireInSameThread_fair() { testTryAcquireInSameThread(true); }
175     public void testTryAcquireInSameThread(boolean fair) {
176     Semaphore s = new Semaphore(2, fair);
177 dl 1.1 assertEquals(2, s.availablePermits());
178     assertTrue(s.tryAcquire());
179     assertTrue(s.tryAcquire());
180     assertEquals(0, s.availablePermits());
181     assertFalse(s.tryAcquire());
182 jsr166 1.28 assertFalse(s.tryAcquire());
183     assertEquals(0, s.availablePermits());
184 dl 1.1 }
185    
186 dl 1.4 /**
187 jsr166 1.28 * timed tryAcquire times out
188 dl 1.5 */
189 jsr166 1.28 public void testTryAcquire_timeout() { testTryAcquire_timeout(false); }
190     public void testTryAcquire_timeout_fair() { testTryAcquire_timeout(true); }
191     public void testTryAcquire_timeout(boolean fair) {
192     Semaphore s = new Semaphore(0, fair);
193     long startTime = System.nanoTime();
194     try { assertFalse(s.tryAcquire(timeoutMillis(), MILLISECONDS)); }
195     catch (InterruptedException e) { threadUnexpectedException(e); }
196     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
197     }
198    
199     /**
200     * timed tryAcquire(N) times out
201     */
202     public void testTryAcquireN_timeout() { testTryAcquireN_timeout(false); }
203     public void testTryAcquireN_timeout_fair() { testTryAcquireN_timeout(true); }
204     public void testTryAcquireN_timeout(boolean fair) {
205     Semaphore s = new Semaphore(2, fair);
206     long startTime = System.nanoTime();
207     try { assertFalse(s.tryAcquire(3, timeoutMillis(), MILLISECONDS)); }
208     catch (InterruptedException e) { threadUnexpectedException(e); }
209     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
210     }
211    
212     /**
213     * acquire(), acquire(N), timed tryAcquired, timed tryAcquire(N)
214     * are interruptible
215     */
216     public void testInterruptible_acquire() { testInterruptible(false, AcquireMethod.acquire); }
217     public void testInterruptible_acquire_fair() { testInterruptible(true, AcquireMethod.acquire); }
218     public void testInterruptible_acquireN() { testInterruptible(false, AcquireMethod.acquireN); }
219     public void testInterruptible_acquireN_fair() { testInterruptible(true, AcquireMethod.acquireN); }
220     public void testInterruptible_tryAcquireTimed() { testInterruptible(false, AcquireMethod.tryAcquireTimed); }
221     public void testInterruptible_tryAcquireTimed_fair() { testInterruptible(true, AcquireMethod.tryAcquireTimed); }
222     public void testInterruptible_tryAcquireTimedN() { testInterruptible(false, AcquireMethod.tryAcquireTimedN); }
223     public void testInterruptible_tryAcquireTimedN_fair() { testInterruptible(true, AcquireMethod.tryAcquireTimedN); }
224     public void testInterruptible(boolean fair, final AcquireMethod acquirer) {
225     final PublicSemaphore s = new PublicSemaphore(0, fair);
226     final Semaphore anotherInterruptPlease = new Semaphore(0, fair);
227     Thread t = newStartedThread(new CheckedRunnable() {
228     public void realRun() {
229     // Interrupt before acquire
230     Thread.currentThread().interrupt();
231     try {
232     acquirer.acquire(s);
233     shouldThrow();
234     } catch (InterruptedException success) {}
235    
236     // Interrupt during acquire
237     try {
238     acquirer.acquire(s);
239     shouldThrow();
240     } catch (InterruptedException success) {}
241    
242     // Interrupt before acquire(N)
243     Thread.currentThread().interrupt();
244     try {
245     acquirer.acquire(s, 3);
246     shouldThrow();
247     } catch (InterruptedException success) {}
248    
249     anotherInterruptPlease.release();
250    
251     // Interrupt during acquire(N)
252     try {
253     acquirer.acquire(s, 3);
254     shouldThrow();
255     } catch (InterruptedException success) {}
256 jsr166 1.19 }});
257    
258 jsr166 1.28 waitForQueuedThread(s, t);
259     t.interrupt();
260     try {
261     assertTrue(anotherInterruptPlease.tryAcquire(LONG_DELAY_MS, MILLISECONDS));
262     } catch (InterruptedException e) { threadUnexpectedException(e); }
263     waitForQueuedThread(s, t);
264     t.interrupt();
265     awaitTermination(t);
266 dl 1.1 }
267    
268 dl 1.4 /**
269 jsr166 1.28 * acquireUninterruptibly(), acquireUninterruptibly(N) are
270     * uninterruptible
271 dl 1.4 */
272 jsr166 1.28 public void testUninterruptible_acquireUninterruptibly() { testUninterruptible(false, AcquireMethod.acquireUninterruptibly); }
273     public void testUninterruptible_acquireUninterruptibly_fair() { testUninterruptible(true, AcquireMethod.acquireUninterruptibly); }
274     public void testUninterruptible_acquireUninterruptiblyN() { testUninterruptible(false, AcquireMethod.acquireUninterruptiblyN); }
275     public void testUninterruptible_acquireUninterruptiblyN_fair() { testUninterruptible(true, AcquireMethod.acquireUninterruptiblyN); }
276     public void testUninterruptible(boolean fair, final AcquireMethod acquirer) {
277     final PublicSemaphore s = new PublicSemaphore(0, fair);
278     final Semaphore anotherInterruptPlease = new Semaphore(0, fair);
279     Thread t = newStartedThread(new CheckedRunnable() {
280 jsr166 1.19 public void realRun() throws InterruptedException {
281 jsr166 1.28 // Interrupt before acquire
282     Thread.currentThread().interrupt();
283     acquirer.acquire(s);
284     assertTrue(Thread.interrupted());
285 dl 1.1
286 jsr166 1.28 anotherInterruptPlease.release();
287 dl 1.5
288 jsr166 1.28 // Interrupt during acquire
289     acquirer.acquire(s);
290     assertTrue(Thread.interrupted());
291 jsr166 1.19 }});
292    
293 jsr166 1.28 waitForQueuedThread(s, t);
294     assertThreadStaysAlive(t);
295 jsr166 1.19 s.release();
296    
297 jsr166 1.28 try {
298     assertTrue(anotherInterruptPlease.tryAcquire(LONG_DELAY_MS, MILLISECONDS));
299     } catch (InterruptedException e) { threadUnexpectedException(e); }
300     waitForQueuedThread(s, t);
301 jsr166 1.19 t.interrupt();
302 jsr166 1.28 assertThreadStaysAlive(t);
303     s.release();
304 jsr166 1.15
305 jsr166 1.28 awaitTermination(t);
306 dl 1.1 }
307 dl 1.2
308 dl 1.4 /**
309 dl 1.8 * hasQueuedThreads reports whether there are waiting threads
310     */
311 jsr166 1.28 public void testHasQueuedThreads() { testHasQueuedThreads(false); }
312     public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
313     public void testHasQueuedThreads(boolean fair) {
314     final PublicSemaphore lock = new PublicSemaphore(1, fair);
315 jsr166 1.19 assertFalse(lock.hasQueuedThreads());
316     lock.acquireUninterruptibly();
317 jsr166 1.28 Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
318     waitForQueuedThread(lock, t1);
319 jsr166 1.19 assertTrue(lock.hasQueuedThreads());
320 jsr166 1.28 Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
321     waitForQueuedThread(lock, t2);
322 jsr166 1.19 assertTrue(lock.hasQueuedThreads());
323     t1.interrupt();
324 jsr166 1.28 awaitTermination(t1);
325 jsr166 1.19 assertTrue(lock.hasQueuedThreads());
326     lock.release();
327 jsr166 1.28 awaitTermination(t2);
328 jsr166 1.19 assertFalse(lock.hasQueuedThreads());
329 jsr166 1.15 }
330 dl 1.8
331     /**
332 dl 1.6 * getQueueLength reports number of waiting threads
333     */
334 jsr166 1.28 public void testGetQueueLength() { testGetQueueLength(false); }
335     public void testGetQueueLength_fair() { testGetQueueLength(true); }
336     public void testGetQueueLength(boolean fair) {
337     final PublicSemaphore lock = new PublicSemaphore(1, fair);
338 jsr166 1.19 assertEquals(0, lock.getQueueLength());
339     lock.acquireUninterruptibly();
340 jsr166 1.28 Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
341     waitForQueuedThread(lock, t1);
342 jsr166 1.19 assertEquals(1, lock.getQueueLength());
343 jsr166 1.28 Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
344     waitForQueuedThread(lock, t2);
345 jsr166 1.19 assertEquals(2, lock.getQueueLength());
346     t1.interrupt();
347 jsr166 1.28 awaitTermination(t1);
348 jsr166 1.19 assertEquals(1, lock.getQueueLength());
349     lock.release();
350 jsr166 1.28 awaitTermination(t2);
351 jsr166 1.19 assertEquals(0, lock.getQueueLength());
352 jsr166 1.15 }
353 dl 1.6
354     /**
355     * getQueuedThreads includes waiting threads
356     */
357 jsr166 1.28 public void testGetQueuedThreads() { testGetQueuedThreads(false); }
358     public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
359     public void testGetQueuedThreads(boolean fair) {
360     final PublicSemaphore lock = new PublicSemaphore(1, fair);
361 jsr166 1.19 assertTrue(lock.getQueuedThreads().isEmpty());
362     lock.acquireUninterruptibly();
363     assertTrue(lock.getQueuedThreads().isEmpty());
364 jsr166 1.28 Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
365     waitForQueuedThread(lock, t1);
366 jsr166 1.19 assertTrue(lock.getQueuedThreads().contains(t1));
367 jsr166 1.28 Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
368     waitForQueuedThread(lock, t2);
369 jsr166 1.19 assertTrue(lock.getQueuedThreads().contains(t1));
370     assertTrue(lock.getQueuedThreads().contains(t2));
371     t1.interrupt();
372 jsr166 1.28 awaitTermination(t1);
373 jsr166 1.19 assertFalse(lock.getQueuedThreads().contains(t1));
374     assertTrue(lock.getQueuedThreads().contains(t2));
375     lock.release();
376 jsr166 1.28 awaitTermination(t2);
377 jsr166 1.19 assertTrue(lock.getQueuedThreads().isEmpty());
378 jsr166 1.15 }
379 dl 1.6
380 dl 1.11 /**
381     * drainPermits reports and removes given number of permits
382     */
383 jsr166 1.28 public void testDrainPermits() { testDrainPermits(false); }
384     public void testDrainPermits_fair() { testDrainPermits(true); }
385     public void testDrainPermits(boolean fair) {
386     Semaphore s = new Semaphore(0, fair);
387 dl 1.11 assertEquals(0, s.availablePermits());
388     assertEquals(0, s.drainPermits());
389     s.release(10);
390     assertEquals(10, s.availablePermits());
391     assertEquals(10, s.drainPermits());
392     assertEquals(0, s.availablePermits());
393     assertEquals(0, s.drainPermits());
394     }
395 dl 1.6
396     /**
397 jsr166 1.28 * release(-N) throws IllegalArgumentException
398 dl 1.6 */
399 jsr166 1.28 public void testReleaseIAE() { testReleaseIAE(false); }
400     public void testReleaseIAE_fair() { testReleaseIAE(true); }
401     public void testReleaseIAE(boolean fair) {
402     Semaphore s = new Semaphore(10, fair);
403     try {
404     s.release(-1);
405     shouldThrow();
406     } catch (IllegalArgumentException success) {}
407 dl 1.6 }
408    
409     /**
410 jsr166 1.28 * reducePermits(-N) throws IllegalArgumentException
411     */
412     public void testReducePermitsIAE() { testReducePermitsIAE(false); }
413     public void testReducePermitsIAE_fair() { testReducePermitsIAE(true); }
414     public void testReducePermitsIAE(boolean fair) {
415     PublicSemaphore s = new PublicSemaphore(10, fair);
416     try {
417     s.reducePermits(-1);
418     shouldThrow();
419     } catch (IllegalArgumentException success) {}
420 dl 1.6 }
421    
422     /**
423 jsr166 1.28 * reducePermits reduces number of permits
424 dl 1.6 */
425 jsr166 1.28 public void testReducePermits() { testReducePermits(false); }
426     public void testReducePermits_fair() { testReducePermits(true); }
427     public void testReducePermits(boolean fair) {
428     PublicSemaphore s = new PublicSemaphore(10, fair);
429     assertEquals(10, s.availablePermits());
430     s.reducePermits(0);
431     assertEquals(10, s.availablePermits());
432     s.reducePermits(1);
433     assertEquals(9, s.availablePermits());
434     s.reducePermits(10);
435     assertEquals(-1, s.availablePermits());
436     s.reducePermits(10);
437     assertEquals(-11, s.availablePermits());
438     s.reducePermits(0);
439     assertEquals(-11, s.availablePermits());
440 dl 1.6 }
441    
442     /**
443 jsr166 1.28 * a reserialized semaphore has same number of permits and
444     * fairness, but no queued threads
445     */
446     public void testSerialization() { testSerialization(false); }
447     public void testSerialization_fair() { testSerialization(true); }
448     public void testSerialization(boolean fair) {
449     try {
450     Semaphore s = new Semaphore(3, fair);
451     s.acquire();
452     s.acquire();
453     s.release();
454    
455     Semaphore clone = serialClone(s);
456     assertEquals(fair, s.isFair());
457     assertEquals(fair, clone.isFair());
458     assertEquals(2, s.availablePermits());
459     assertEquals(2, clone.availablePermits());
460     clone.acquire();
461     clone.acquire();
462     clone.release();
463     assertEquals(2, s.availablePermits());
464     assertEquals(1, clone.availablePermits());
465    
466     s = new Semaphore(0, fair);
467     Thread t = newStartedThread(new InterruptibleLockRunnable(s));
468     waitForQueuedThreads(s);
469     clone = serialClone(s);
470     assertEquals(fair, s.isFair());
471     assertEquals(fair, clone.isFair());
472     assertEquals(0, s.availablePermits());
473     assertEquals(0, clone.availablePermits());
474     assertTrue(s.hasQueuedThreads());
475     assertFalse(clone.hasQueuedThreads());
476     s.release();
477     awaitTermination(t);
478     assertFalse(s.hasQueuedThreads());
479     assertFalse(clone.hasQueuedThreads());
480     } catch (InterruptedException e) { threadUnexpectedException(e); }
481 dl 1.6 }
482    
483     /**
484 dl 1.9 * tryAcquire(n) succeeds when sufficient permits, else fails
485 dl 1.6 */
486 jsr166 1.28 public void testTryAcquireNInSameThread() { testTryAcquireNInSameThread(false); }
487     public void testTryAcquireNInSameThread_fair() { testTryAcquireNInSameThread(true); }
488     public void testTryAcquireNInSameThread(boolean fair) {
489     Semaphore s = new Semaphore(2, fair);
490     assertEquals(2, s.availablePermits());
491     assertFalse(s.tryAcquire(3));
492 dl 1.6 assertEquals(2, s.availablePermits());
493     assertTrue(s.tryAcquire(2));
494     assertEquals(0, s.availablePermits());
495 jsr166 1.28 assertFalse(s.tryAcquire(1));
496     assertFalse(s.tryAcquire(2));
497     assertEquals(0, s.availablePermits());
498 dl 1.6 }
499    
500     /**
501 jsr166 1.28 * acquire succeeds if permits available
502 dl 1.6 */
503 jsr166 1.28 public void testReleaseAcquireSameThread_acquire() { testReleaseAcquireSameThread(false, AcquireMethod.acquire); }
504     public void testReleaseAcquireSameThread_acquire_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquire); }
505     public void testReleaseAcquireSameThread_acquireN() { testReleaseAcquireSameThread(false, AcquireMethod.acquireN); }
506     public void testReleaseAcquireSameThread_acquireN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquireN); }
507     public void testReleaseAcquireSameThread_acquireUninterruptibly() { testReleaseAcquireSameThread(false, AcquireMethod.acquireUninterruptibly); }
508     public void testReleaseAcquireSameThread_acquireUninterruptibly_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquireUninterruptibly); }
509     public void testReleaseAcquireSameThread_acquireUninterruptiblyN() { testReleaseAcquireSameThread(false, AcquireMethod.acquireUninterruptibly); }
510     public void testReleaseAcquireSameThread_acquireUninterruptiblyN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquireUninterruptibly); }
511     public void testReleaseAcquireSameThread_tryAcquire() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquire); }
512     public void testReleaseAcquireSameThread_tryAcquire_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquire); }
513     public void testReleaseAcquireSameThread_tryAcquireN() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireN); }
514     public void testReleaseAcquireSameThread_tryAcquireN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireN); }
515     public void testReleaseAcquireSameThread_tryAcquireTimed() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireTimed); }
516     public void testReleaseAcquireSameThread_tryAcquireTimed_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireTimed); }
517     public void testReleaseAcquireSameThread_tryAcquireTimedN() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireTimedN); }
518     public void testReleaseAcquireSameThread_tryAcquireTimedN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireTimedN); }
519     public void testReleaseAcquireSameThread(boolean fair,
520     final AcquireMethod acquirer) {
521     Semaphore s = new Semaphore(1, fair);
522     for (int i = 1; i < 6; i++) {
523     s.release(i);
524     assertEquals(1 + i, s.availablePermits());
525     try {
526     acquirer.acquire(s, i);
527     } catch (InterruptedException e) { threadUnexpectedException(e); }
528     assertEquals(1, s.availablePermits());
529     }
530 dl 1.6 }
531    
532     /**
533 jsr166 1.28 * release in one thread enables acquire in another thread
534 dl 1.6 */
535 jsr166 1.28 public void testReleaseAcquireDifferentThreads_acquire() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquire); }
536     public void testReleaseAcquireDifferentThreads_acquire_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquire); }
537     public void testReleaseAcquireDifferentThreads_acquireN() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireN); }
538     public void testReleaseAcquireDifferentThreads_acquireN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireN); }
539     public void testReleaseAcquireDifferentThreads_acquireUninterruptibly() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireUninterruptibly); }
540     public void testReleaseAcquireDifferentThreads_acquireUninterruptibly_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireUninterruptibly); }
541     public void testReleaseAcquireDifferentThreads_acquireUninterruptiblyN() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireUninterruptibly); }
542     public void testReleaseAcquireDifferentThreads_acquireUninterruptiblyN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireUninterruptibly); }
543     public void testReleaseAcquireDifferentThreads_tryAcquireTimed() { testReleaseAcquireDifferentThreads(false, AcquireMethod.tryAcquireTimed); }
544     public void testReleaseAcquireDifferentThreads_tryAcquireTimed_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.tryAcquireTimed); }
545     public void testReleaseAcquireDifferentThreads_tryAcquireTimedN() { testReleaseAcquireDifferentThreads(false, AcquireMethod.tryAcquireTimedN); }
546     public void testReleaseAcquireDifferentThreads_tryAcquireTimedN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.tryAcquireTimedN); }
547     public void testReleaseAcquireDifferentThreads(boolean fair,
548     final AcquireMethod acquirer) {
549     final Semaphore s = new Semaphore(0, fair);
550     final int rounds = 4;
551     long startTime = System.nanoTime();
552     Thread t = newStartedThread(new CheckedRunnable() {
553     public void realRun() throws InterruptedException {
554     for (int i = 0; i < rounds; i++) {
555     assertFalse(s.hasQueuedThreads());
556     if (i % 2 == 0)
557     acquirer.acquire(s);
558     else
559     acquirer.acquire(s, 3);
560     }}});
561    
562     for (int i = 0; i < rounds; i++) {
563     while (! (s.availablePermits() == 0 && s.hasQueuedThreads()))
564     Thread.yield();
565     assertTrue(t.isAlive());
566     if (i % 2 == 0)
567     s.release();
568     else
569     s.release(3);
570     }
571     awaitTermination(t);
572     assertEquals(0, s.availablePermits());
573     assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
574 dl 1.6 }
575    
576     /**
577 jsr166 1.28 * fair locks are strictly FIFO
578 dl 1.6 */
579 jsr166 1.28 public void testFairLocksFifo() {
580     final PublicSemaphore s = new PublicSemaphore(1, true);
581     final CountDownLatch pleaseRelease = new CountDownLatch(1);
582     Thread t1 = newStartedThread(new CheckedRunnable() {
583 jsr166 1.20 public void realRun() throws InterruptedException {
584 jsr166 1.28 // Will block; permits are available, but not three
585     s.acquire(3);
586 jsr166 1.19 }});
587    
588 jsr166 1.28 waitForQueuedThreads(s);
589 dl 1.6
590 jsr166 1.28 Thread t2 = newStartedThread(new CheckedRunnable() {
591 jsr166 1.20 public void realRun() throws InterruptedException {
592 jsr166 1.28 // Will fail, even though 1 permit is available
593     assertFalse(s.tryAcquire(0L, MILLISECONDS));
594     assertFalse(s.tryAcquire(1, 0L, MILLISECONDS));
595    
596     // untimed tryAcquire will barge and succeed
597     assertTrue(s.tryAcquire());
598 jsr166 1.19 s.release(2);
599 jsr166 1.28 assertTrue(s.tryAcquire(2));
600     s.release();
601    
602     pleaseRelease.countDown();
603     // Will queue up behind t1, even though 1 permit is available
604 jsr166 1.19 s.acquire();
605     }});
606    
607 jsr166 1.28 await(pleaseRelease);
608     waitForQueuedThread(s, t2);
609 jsr166 1.19 s.release(2);
610 jsr166 1.28 awaitTermination(t1);
611     assertTrue(t2.isAlive());
612 jsr166 1.19 s.release();
613 jsr166 1.28 awaitTermination(t2);
614     }
615 dl 1.6
616 dl 1.14 /**
617     * toString indicates current number of permits
618     */
619 jsr166 1.28 public void testToString() { testToString(false); }
620     public void testToString_fair() { testToString(true); }
621     public void testToString(boolean fair) {
622     PublicSemaphore s = new PublicSemaphore(0, fair);
623     assertTrue(s.toString().contains("Permits = 0"));
624 dl 1.14 s.release();
625 jsr166 1.28 assertTrue(s.toString().contains("Permits = 1"));
626     s.release(2);
627     assertTrue(s.toString().contains("Permits = 3"));
628     s.reducePermits(5);
629     assertTrue(s.toString().contains("Permits = -2"));
630 dl 1.14 }
631 dl 1.2
632 dl 1.1 }