ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SemaphoreTest.java
Revision: 1.37
Committed: Sat May 13 23:50:00 2017 UTC (7 years ago) by jsr166
Branch: MAIN
Changes since 1.36: +2 -2 lines
Log Message:
claw back some millis using assertThreadBlocks

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