ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SemaphoreTest.java
Revision: 1.42
Committed: Mon May 29 19:15:03 2017 UTC (6 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.41: +4 -2 lines
Log Message:
more timeout handling rework; remove most uses of SMALL_DELAY_MS; randomize timeouts and TimeUnits; remove hardcoded 5 second timeouts

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