ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SemaphoreTest.java
Revision: 1.43
Committed: Tue Jan 23 20:44:11 2018 UTC (6 years, 3 months ago) by jsr166
Branch: MAIN
Changes since 1.42: +2 -3 lines
Log Message:
migrate from AssertionFailedError to AssertionError

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