ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SemaphoreTest.java
Revision: 1.31
Committed: Mon Jul 25 19:01:08 2011 UTC (12 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.30: +1 -1 lines
Log Message:
s/assert/assertTrue/

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 jsr166 1.31 assertTrue(s.hasQueuedThreads());
76 jsr166 1.28 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 jsr166 1.30 final Semaphore pleaseInterrupt = new Semaphore(0, fair);
227 jsr166 1.28 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 jsr166 1.30 pleaseInterrupt.release();
250 jsr166 1.28
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 jsr166 1.30 await(pleaseInterrupt);
261 jsr166 1.28 waitForQueuedThread(s, t);
262     t.interrupt();
263     awaitTermination(t);
264 dl 1.1 }
265    
266 dl 1.4 /**
267 jsr166 1.28 * acquireUninterruptibly(), acquireUninterruptibly(N) are
268     * uninterruptible
269 dl 1.4 */
270 jsr166 1.28 public void testUninterruptible_acquireUninterruptibly() { testUninterruptible(false, AcquireMethod.acquireUninterruptibly); }
271     public void testUninterruptible_acquireUninterruptibly_fair() { testUninterruptible(true, AcquireMethod.acquireUninterruptibly); }
272     public void testUninterruptible_acquireUninterruptiblyN() { testUninterruptible(false, AcquireMethod.acquireUninterruptiblyN); }
273     public void testUninterruptible_acquireUninterruptiblyN_fair() { testUninterruptible(true, AcquireMethod.acquireUninterruptiblyN); }
274     public void testUninterruptible(boolean fair, final AcquireMethod acquirer) {
275     final PublicSemaphore s = new PublicSemaphore(0, fair);
276 jsr166 1.30 final Semaphore pleaseInterrupt = new Semaphore(-1, fair);
277    
278     Thread t1 = newStartedThread(new CheckedRunnable() {
279 jsr166 1.19 public void realRun() throws InterruptedException {
280 jsr166 1.28 // Interrupt before acquire
281 jsr166 1.30 pleaseInterrupt.release();
282 jsr166 1.28 Thread.currentThread().interrupt();
283     acquirer.acquire(s);
284     assertTrue(Thread.interrupted());
285 jsr166 1.30 }});
286 dl 1.1
287 jsr166 1.30 Thread t2 = newStartedThread(new CheckedRunnable() {
288     public void realRun() throws InterruptedException {
289 jsr166 1.28 // Interrupt during acquire
290 jsr166 1.30 pleaseInterrupt.release();
291 jsr166 1.28 acquirer.acquire(s);
292     assertTrue(Thread.interrupted());
293 jsr166 1.19 }});
294    
295 jsr166 1.30 await(pleaseInterrupt);
296     waitForQueuedThread(s, t1);
297     waitForQueuedThread(s, t2);
298     t2.interrupt();
299    
300     assertThreadStaysAlive(t1);
301     assertTrue(t2.isAlive());
302 jsr166 1.19
303 jsr166 1.30 s.release(2);
304 jsr166 1.15
305 jsr166 1.30 awaitTermination(t1);
306     awaitTermination(t2);
307 dl 1.1 }
308 dl 1.2
309 dl 1.4 /**
310 dl 1.8 * hasQueuedThreads reports whether there are waiting threads
311     */
312 jsr166 1.28 public void testHasQueuedThreads() { testHasQueuedThreads(false); }
313     public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
314     public void testHasQueuedThreads(boolean fair) {
315     final PublicSemaphore lock = new PublicSemaphore(1, fair);
316 jsr166 1.19 assertFalse(lock.hasQueuedThreads());
317     lock.acquireUninterruptibly();
318 jsr166 1.28 Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
319     waitForQueuedThread(lock, t1);
320 jsr166 1.19 assertTrue(lock.hasQueuedThreads());
321 jsr166 1.28 Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
322     waitForQueuedThread(lock, t2);
323 jsr166 1.19 assertTrue(lock.hasQueuedThreads());
324     t1.interrupt();
325 jsr166 1.28 awaitTermination(t1);
326 jsr166 1.19 assertTrue(lock.hasQueuedThreads());
327     lock.release();
328 jsr166 1.28 awaitTermination(t2);
329 jsr166 1.19 assertFalse(lock.hasQueuedThreads());
330 jsr166 1.15 }
331 dl 1.8
332     /**
333 dl 1.6 * getQueueLength reports number of waiting threads
334     */
335 jsr166 1.28 public void testGetQueueLength() { testGetQueueLength(false); }
336     public void testGetQueueLength_fair() { testGetQueueLength(true); }
337     public void testGetQueueLength(boolean fair) {
338     final PublicSemaphore lock = new PublicSemaphore(1, fair);
339 jsr166 1.19 assertEquals(0, lock.getQueueLength());
340     lock.acquireUninterruptibly();
341 jsr166 1.28 Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
342     waitForQueuedThread(lock, t1);
343 jsr166 1.19 assertEquals(1, lock.getQueueLength());
344 jsr166 1.28 Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
345     waitForQueuedThread(lock, t2);
346 jsr166 1.19 assertEquals(2, lock.getQueueLength());
347     t1.interrupt();
348 jsr166 1.28 awaitTermination(t1);
349 jsr166 1.19 assertEquals(1, lock.getQueueLength());
350     lock.release();
351 jsr166 1.28 awaitTermination(t2);
352 jsr166 1.19 assertEquals(0, lock.getQueueLength());
353 jsr166 1.15 }
354 dl 1.6
355     /**
356     * getQueuedThreads includes waiting threads
357     */
358 jsr166 1.28 public void testGetQueuedThreads() { testGetQueuedThreads(false); }
359     public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
360     public void testGetQueuedThreads(boolean fair) {
361     final PublicSemaphore lock = new PublicSemaphore(1, fair);
362 jsr166 1.19 assertTrue(lock.getQueuedThreads().isEmpty());
363     lock.acquireUninterruptibly();
364     assertTrue(lock.getQueuedThreads().isEmpty());
365 jsr166 1.28 Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
366     waitForQueuedThread(lock, t1);
367 jsr166 1.19 assertTrue(lock.getQueuedThreads().contains(t1));
368 jsr166 1.28 Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
369     waitForQueuedThread(lock, t2);
370 jsr166 1.19 assertTrue(lock.getQueuedThreads().contains(t1));
371     assertTrue(lock.getQueuedThreads().contains(t2));
372     t1.interrupt();
373 jsr166 1.28 awaitTermination(t1);
374 jsr166 1.19 assertFalse(lock.getQueuedThreads().contains(t1));
375     assertTrue(lock.getQueuedThreads().contains(t2));
376     lock.release();
377 jsr166 1.28 awaitTermination(t2);
378 jsr166 1.19 assertTrue(lock.getQueuedThreads().isEmpty());
379 jsr166 1.15 }
380 dl 1.6
381 dl 1.11 /**
382     * drainPermits reports and removes given number of permits
383     */
384 jsr166 1.28 public void testDrainPermits() { testDrainPermits(false); }
385     public void testDrainPermits_fair() { testDrainPermits(true); }
386     public void testDrainPermits(boolean fair) {
387     Semaphore s = new Semaphore(0, fair);
388 dl 1.11 assertEquals(0, s.availablePermits());
389     assertEquals(0, s.drainPermits());
390     s.release(10);
391     assertEquals(10, s.availablePermits());
392     assertEquals(10, s.drainPermits());
393     assertEquals(0, s.availablePermits());
394     assertEquals(0, s.drainPermits());
395     }
396 dl 1.6
397     /**
398 jsr166 1.28 * release(-N) throws IllegalArgumentException
399 dl 1.6 */
400 jsr166 1.28 public void testReleaseIAE() { testReleaseIAE(false); }
401     public void testReleaseIAE_fair() { testReleaseIAE(true); }
402     public void testReleaseIAE(boolean fair) {
403     Semaphore s = new Semaphore(10, fair);
404     try {
405     s.release(-1);
406     shouldThrow();
407     } catch (IllegalArgumentException success) {}
408 dl 1.6 }
409    
410     /**
411 jsr166 1.28 * reducePermits(-N) throws IllegalArgumentException
412     */
413     public void testReducePermitsIAE() { testReducePermitsIAE(false); }
414     public void testReducePermitsIAE_fair() { testReducePermitsIAE(true); }
415     public void testReducePermitsIAE(boolean fair) {
416     PublicSemaphore s = new PublicSemaphore(10, fair);
417     try {
418     s.reducePermits(-1);
419     shouldThrow();
420     } catch (IllegalArgumentException success) {}
421 dl 1.6 }
422    
423     /**
424 jsr166 1.28 * reducePermits reduces number of permits
425 dl 1.6 */
426 jsr166 1.28 public void testReducePermits() { testReducePermits(false); }
427     public void testReducePermits_fair() { testReducePermits(true); }
428     public void testReducePermits(boolean fair) {
429     PublicSemaphore s = new PublicSemaphore(10, fair);
430     assertEquals(10, s.availablePermits());
431     s.reducePermits(0);
432     assertEquals(10, s.availablePermits());
433     s.reducePermits(1);
434     assertEquals(9, s.availablePermits());
435     s.reducePermits(10);
436     assertEquals(-1, s.availablePermits());
437     s.reducePermits(10);
438     assertEquals(-11, s.availablePermits());
439     s.reducePermits(0);
440     assertEquals(-11, s.availablePermits());
441 dl 1.6 }
442    
443     /**
444 jsr166 1.28 * a reserialized semaphore has same number of permits and
445     * fairness, but no queued threads
446     */
447     public void testSerialization() { testSerialization(false); }
448     public void testSerialization_fair() { testSerialization(true); }
449     public void testSerialization(boolean fair) {
450     try {
451     Semaphore s = new Semaphore(3, fair);
452     s.acquire();
453     s.acquire();
454     s.release();
455    
456     Semaphore clone = serialClone(s);
457     assertEquals(fair, s.isFair());
458     assertEquals(fair, clone.isFair());
459     assertEquals(2, s.availablePermits());
460     assertEquals(2, clone.availablePermits());
461     clone.acquire();
462     clone.acquire();
463     clone.release();
464     assertEquals(2, s.availablePermits());
465     assertEquals(1, clone.availablePermits());
466    
467     s = new Semaphore(0, fair);
468     Thread t = newStartedThread(new InterruptibleLockRunnable(s));
469     waitForQueuedThreads(s);
470     clone = serialClone(s);
471     assertEquals(fair, s.isFair());
472     assertEquals(fair, clone.isFair());
473     assertEquals(0, s.availablePermits());
474     assertEquals(0, clone.availablePermits());
475     assertTrue(s.hasQueuedThreads());
476     assertFalse(clone.hasQueuedThreads());
477     s.release();
478     awaitTermination(t);
479     assertFalse(s.hasQueuedThreads());
480     assertFalse(clone.hasQueuedThreads());
481     } catch (InterruptedException e) { threadUnexpectedException(e); }
482 dl 1.6 }
483    
484     /**
485 dl 1.9 * tryAcquire(n) succeeds when sufficient permits, else fails
486 dl 1.6 */
487 jsr166 1.28 public void testTryAcquireNInSameThread() { testTryAcquireNInSameThread(false); }
488     public void testTryAcquireNInSameThread_fair() { testTryAcquireNInSameThread(true); }
489     public void testTryAcquireNInSameThread(boolean fair) {
490     Semaphore s = new Semaphore(2, fair);
491     assertEquals(2, s.availablePermits());
492     assertFalse(s.tryAcquire(3));
493 dl 1.6 assertEquals(2, s.availablePermits());
494     assertTrue(s.tryAcquire(2));
495     assertEquals(0, s.availablePermits());
496 jsr166 1.28 assertFalse(s.tryAcquire(1));
497     assertFalse(s.tryAcquire(2));
498     assertEquals(0, s.availablePermits());
499 dl 1.6 }
500    
501     /**
502 jsr166 1.28 * acquire succeeds if permits available
503 dl 1.6 */
504 jsr166 1.28 public void testReleaseAcquireSameThread_acquire() { testReleaseAcquireSameThread(false, AcquireMethod.acquire); }
505     public void testReleaseAcquireSameThread_acquire_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquire); }
506     public void testReleaseAcquireSameThread_acquireN() { testReleaseAcquireSameThread(false, AcquireMethod.acquireN); }
507     public void testReleaseAcquireSameThread_acquireN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquireN); }
508     public void testReleaseAcquireSameThread_acquireUninterruptibly() { testReleaseAcquireSameThread(false, AcquireMethod.acquireUninterruptibly); }
509     public void testReleaseAcquireSameThread_acquireUninterruptibly_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquireUninterruptibly); }
510     public void testReleaseAcquireSameThread_acquireUninterruptiblyN() { testReleaseAcquireSameThread(false, AcquireMethod.acquireUninterruptibly); }
511     public void testReleaseAcquireSameThread_acquireUninterruptiblyN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquireUninterruptibly); }
512     public void testReleaseAcquireSameThread_tryAcquire() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquire); }
513     public void testReleaseAcquireSameThread_tryAcquire_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquire); }
514     public void testReleaseAcquireSameThread_tryAcquireN() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireN); }
515     public void testReleaseAcquireSameThread_tryAcquireN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireN); }
516     public void testReleaseAcquireSameThread_tryAcquireTimed() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireTimed); }
517     public void testReleaseAcquireSameThread_tryAcquireTimed_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireTimed); }
518     public void testReleaseAcquireSameThread_tryAcquireTimedN() { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireTimedN); }
519     public void testReleaseAcquireSameThread_tryAcquireTimedN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireTimedN); }
520     public void testReleaseAcquireSameThread(boolean fair,
521     final AcquireMethod acquirer) {
522     Semaphore s = new Semaphore(1, fair);
523     for (int i = 1; i < 6; i++) {
524     s.release(i);
525     assertEquals(1 + i, s.availablePermits());
526     try {
527     acquirer.acquire(s, i);
528     } catch (InterruptedException e) { threadUnexpectedException(e); }
529     assertEquals(1, s.availablePermits());
530     }
531 dl 1.6 }
532    
533     /**
534 jsr166 1.28 * release in one thread enables acquire in another thread
535 dl 1.6 */
536 jsr166 1.28 public void testReleaseAcquireDifferentThreads_acquire() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquire); }
537     public void testReleaseAcquireDifferentThreads_acquire_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquire); }
538     public void testReleaseAcquireDifferentThreads_acquireN() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireN); }
539     public void testReleaseAcquireDifferentThreads_acquireN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireN); }
540     public void testReleaseAcquireDifferentThreads_acquireUninterruptibly() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireUninterruptibly); }
541     public void testReleaseAcquireDifferentThreads_acquireUninterruptibly_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireUninterruptibly); }
542     public void testReleaseAcquireDifferentThreads_acquireUninterruptiblyN() { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireUninterruptibly); }
543     public void testReleaseAcquireDifferentThreads_acquireUninterruptiblyN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireUninterruptibly); }
544     public void testReleaseAcquireDifferentThreads_tryAcquireTimed() { testReleaseAcquireDifferentThreads(false, AcquireMethod.tryAcquireTimed); }
545     public void testReleaseAcquireDifferentThreads_tryAcquireTimed_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.tryAcquireTimed); }
546     public void testReleaseAcquireDifferentThreads_tryAcquireTimedN() { testReleaseAcquireDifferentThreads(false, AcquireMethod.tryAcquireTimedN); }
547     public void testReleaseAcquireDifferentThreads_tryAcquireTimedN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.tryAcquireTimedN); }
548     public void testReleaseAcquireDifferentThreads(boolean fair,
549     final AcquireMethod acquirer) {
550     final Semaphore s = new Semaphore(0, fair);
551     final int rounds = 4;
552     long startTime = System.nanoTime();
553     Thread t = newStartedThread(new CheckedRunnable() {
554     public void realRun() throws InterruptedException {
555     for (int i = 0; i < rounds; i++) {
556     assertFalse(s.hasQueuedThreads());
557     if (i % 2 == 0)
558     acquirer.acquire(s);
559     else
560     acquirer.acquire(s, 3);
561     }}});
562    
563     for (int i = 0; i < rounds; i++) {
564     while (! (s.availablePermits() == 0 && s.hasQueuedThreads()))
565     Thread.yield();
566     assertTrue(t.isAlive());
567     if (i % 2 == 0)
568     s.release();
569     else
570     s.release(3);
571     }
572     awaitTermination(t);
573     assertEquals(0, s.availablePermits());
574     assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
575 dl 1.6 }
576    
577     /**
578 jsr166 1.28 * fair locks are strictly FIFO
579 dl 1.6 */
580 jsr166 1.28 public void testFairLocksFifo() {
581     final PublicSemaphore s = new PublicSemaphore(1, true);
582     final CountDownLatch pleaseRelease = new CountDownLatch(1);
583     Thread t1 = newStartedThread(new CheckedRunnable() {
584 jsr166 1.20 public void realRun() throws InterruptedException {
585 jsr166 1.28 // Will block; permits are available, but not three
586     s.acquire(3);
587 jsr166 1.19 }});
588    
589 jsr166 1.28 waitForQueuedThreads(s);
590 dl 1.6
591 jsr166 1.28 Thread t2 = newStartedThread(new CheckedRunnable() {
592 jsr166 1.20 public void realRun() throws InterruptedException {
593 jsr166 1.28 // Will fail, even though 1 permit is available
594     assertFalse(s.tryAcquire(0L, MILLISECONDS));
595     assertFalse(s.tryAcquire(1, 0L, MILLISECONDS));
596    
597     // untimed tryAcquire will barge and succeed
598     assertTrue(s.tryAcquire());
599 jsr166 1.19 s.release(2);
600 jsr166 1.28 assertTrue(s.tryAcquire(2));
601     s.release();
602    
603     pleaseRelease.countDown();
604     // Will queue up behind t1, even though 1 permit is available
605 jsr166 1.19 s.acquire();
606     }});
607    
608 jsr166 1.28 await(pleaseRelease);
609     waitForQueuedThread(s, t2);
610 jsr166 1.19 s.release(2);
611 jsr166 1.28 awaitTermination(t1);
612     assertTrue(t2.isAlive());
613 jsr166 1.19 s.release();
614 jsr166 1.28 awaitTermination(t2);
615     }
616 dl 1.6
617 dl 1.14 /**
618     * toString indicates current number of permits
619     */
620 jsr166 1.28 public void testToString() { testToString(false); }
621     public void testToString_fair() { testToString(true); }
622     public void testToString(boolean fair) {
623     PublicSemaphore s = new PublicSemaphore(0, fair);
624     assertTrue(s.toString().contains("Permits = 0"));
625 dl 1.14 s.release();
626 jsr166 1.28 assertTrue(s.toString().contains("Permits = 1"));
627     s.release(2);
628     assertTrue(s.toString().contains("Permits = 3"));
629     s.reducePermits(5);
630     assertTrue(s.toString().contains("Permits = -2"));
631 dl 1.14 }
632 dl 1.2
633 dl 1.1 }