ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/SemaphoreTest.java
Revision: 1.28
Committed: Tue May 24 23:43:14 2011 UTC (12 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.27: +428 -562 lines
Log Message:
various test improvements

File Contents

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