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