/[cvs]/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
ViewVC logotype

Contents of /jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.61 - (show annotations)
Tue Nov 28 18:06:55 2017 UTC (20 months, 3 weeks ago) by jsr166
Branch: MAIN
Changes since 1.60: +1 -1 lines
use DISABLED_ prefix for disabled tests

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 static java.util.concurrent.TimeUnit.MILLISECONDS;
10 import static java.util.concurrent.TimeUnit.NANOSECONDS;
11
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.Collection;
15 import java.util.HashSet;
16 import java.util.concurrent.ThreadLocalRandom;
17 import java.util.concurrent.locks.AbstractQueuedSynchronizer;
18 import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject;
19
20 import junit.framework.AssertionFailedError;
21 import junit.framework.Test;
22 import junit.framework.TestSuite;
23
24 @SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom
25 public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
26 public static void main(String[] args) {
27 main(suite(), args);
28 }
29 public static Test suite() {
30 return new TestSuite(AbstractQueuedSynchronizerTest.class);
31 }
32
33 /**
34 * A simple mutex class, adapted from the class javadoc. Exclusive
35 * acquire tests exercise this as a sample user extension. Other
36 * methods/features of AbstractQueuedSynchronizer are tested via
37 * other test classes, including those for ReentrantLock,
38 * ReentrantReadWriteLock, and Semaphore.
39 *
40 * Unlike the javadoc sample, we don't track owner thread via
41 * AbstractOwnableSynchronizer methods.
42 */
43 static class Mutex extends AbstractQueuedSynchronizer {
44 /** An eccentric value for locked synchronizer state. */
45 static final int LOCKED = (1 << 31) | (1 << 15);
46
47 static final int UNLOCKED = 0;
48
49 /** Owner thread is untracked, so this is really just isLocked(). */
50 @Override public boolean isHeldExclusively() {
51 int state = getState();
52 assertTrue(state == UNLOCKED || state == LOCKED);
53 return state == LOCKED;
54 }
55
56 @Override protected boolean tryAcquire(int acquires) {
57 assertEquals(LOCKED, acquires);
58 return compareAndSetState(UNLOCKED, LOCKED);
59 }
60
61 @Override protected boolean tryRelease(int releases) {
62 if (getState() != LOCKED) throw new IllegalMonitorStateException();
63 assertEquals(LOCKED, releases);
64 setState(UNLOCKED);
65 return true;
66 }
67
68 public boolean tryAcquireNanos(long nanos) throws InterruptedException {
69 return tryAcquireNanos(LOCKED, nanos);
70 }
71
72 public boolean tryAcquire() {
73 return tryAcquire(LOCKED);
74 }
75
76 public boolean tryRelease() {
77 return tryRelease(LOCKED);
78 }
79
80 public void acquire() {
81 acquire(LOCKED);
82 }
83
84 public void acquireInterruptibly() throws InterruptedException {
85 acquireInterruptibly(LOCKED);
86 }
87
88 public void release() {
89 release(LOCKED);
90 }
91
92 /** Faux-Implements Lock.newCondition(). */
93 public ConditionObject newCondition() {
94 return new ConditionObject();
95 }
96 }
97
98 /**
99 * A minimal latch class, to test shared mode.
100 */
101 static class BooleanLatch extends AbstractQueuedSynchronizer {
102 public boolean isSignalled() { return getState() != 0; }
103
104 public int tryAcquireShared(int ignore) {
105 return isSignalled() ? 1 : -1;
106 }
107
108 public boolean tryReleaseShared(int ignore) {
109 setState(1);
110 return true;
111 }
112 }
113
114 /**
115 * A runnable calling acquireInterruptibly that does not expect to
116 * be interrupted.
117 */
118 class InterruptibleSyncRunnable extends CheckedRunnable {
119 final Mutex sync;
120 InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; }
121 public void realRun() throws InterruptedException {
122 sync.acquireInterruptibly();
123 }
124 }
125
126 /**
127 * A runnable calling acquireInterruptibly that expects to be
128 * interrupted.
129 */
130 class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
131 final Mutex sync;
132 InterruptedSyncRunnable(Mutex sync) { this.sync = sync; }
133 public void realRun() throws InterruptedException {
134 sync.acquireInterruptibly();
135 }
136 }
137
138 /** A constant to clarify calls to checking methods below. */
139 static final Thread[] NO_THREADS = new Thread[0];
140
141 /**
142 * Spin-waits until sync.isQueued(t) becomes true.
143 */
144 void waitForQueuedThread(AbstractQueuedSynchronizer sync, Thread t) {
145 long startTime = System.nanoTime();
146 while (!sync.isQueued(t)) {
147 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
148 throw new AssertionFailedError("timed out");
149 Thread.yield();
150 }
151 assertTrue(t.isAlive());
152 }
153
154 /**
155 * Checks that sync has exactly the given queued threads.
156 */
157 void assertHasQueuedThreads(AbstractQueuedSynchronizer sync,
158 Thread... expected) {
159 Collection<Thread> actual = sync.getQueuedThreads();
160 assertEquals(expected.length > 0, sync.hasQueuedThreads());
161 assertEquals(expected.length, sync.getQueueLength());
162 assertEquals(expected.length, actual.size());
163 assertEquals(expected.length == 0, actual.isEmpty());
164 assertEquals(new HashSet<Thread>(actual),
165 new HashSet<Thread>(Arrays.asList(expected)));
166 }
167
168 /**
169 * Checks that sync has exactly the given (exclusive) queued threads.
170 */
171 void assertHasExclusiveQueuedThreads(AbstractQueuedSynchronizer sync,
172 Thread... expected) {
173 assertHasQueuedThreads(sync, expected);
174 assertEquals(new HashSet<Thread>(sync.getExclusiveQueuedThreads()),
175 new HashSet<Thread>(sync.getQueuedThreads()));
176 assertEquals(0, sync.getSharedQueuedThreads().size());
177 assertTrue(sync.getSharedQueuedThreads().isEmpty());
178 }
179
180 /**
181 * Checks that sync has exactly the given (shared) queued threads.
182 */
183 void assertHasSharedQueuedThreads(AbstractQueuedSynchronizer sync,
184 Thread... expected) {
185 assertHasQueuedThreads(sync, expected);
186 assertEquals(new HashSet<Thread>(sync.getSharedQueuedThreads()),
187 new HashSet<Thread>(sync.getQueuedThreads()));
188 assertEquals(0, sync.getExclusiveQueuedThreads().size());
189 assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
190 }
191
192 /**
193 * Checks that condition c has exactly the given waiter threads,
194 * after acquiring mutex.
195 */
196 void assertHasWaitersUnlocked(Mutex sync, ConditionObject c,
197 Thread... threads) {
198 sync.acquire();
199 assertHasWaitersLocked(sync, c, threads);
200 sync.release();
201 }
202
203 /**
204 * Checks that condition c has exactly the given waiter threads.
205 */
206 void assertHasWaitersLocked(Mutex sync, ConditionObject c,
207 Thread... threads) {
208 assertEquals(threads.length > 0, sync.hasWaiters(c));
209 assertEquals(threads.length, sync.getWaitQueueLength(c));
210 assertEquals(threads.length == 0, sync.getWaitingThreads(c).isEmpty());
211 assertEquals(threads.length, sync.getWaitingThreads(c).size());
212 assertEquals(new HashSet<Thread>(sync.getWaitingThreads(c)),
213 new HashSet<Thread>(Arrays.asList(threads)));
214 }
215
216 enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
217
218 /**
219 * Awaits condition using the specified AwaitMethod.
220 */
221 void await(ConditionObject c, AwaitMethod awaitMethod)
222 throws InterruptedException {
223 long timeoutMillis = 2 * LONG_DELAY_MS;
224 switch (awaitMethod) {
225 case await:
226 c.await();
227 break;
228 case awaitTimed:
229 assertTrue(c.await(timeoutMillis, MILLISECONDS));
230 break;
231 case awaitNanos:
232 long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
233 long nanosRemaining = c.awaitNanos(nanosTimeout);
234 assertTrue(nanosRemaining > 0);
235 break;
236 case awaitUntil:
237 assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
238 break;
239 default:
240 throw new AssertionError();
241 }
242 }
243
244 /**
245 * Checks that awaiting the given condition times out (using the
246 * default timeout duration).
247 */
248 void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
249 final long timeoutMillis = timeoutMillis();
250 final long startTime;
251 try {
252 switch (awaitMethod) {
253 case awaitTimed:
254 startTime = System.nanoTime();
255 assertFalse(c.await(timeoutMillis, MILLISECONDS));
256 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
257 break;
258 case awaitNanos:
259 startTime = System.nanoTime();
260 long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
261 long nanosRemaining = c.awaitNanos(nanosTimeout);
262 assertTrue(nanosRemaining <= 0);
263 assertTrue(nanosRemaining > -MILLISECONDS.toNanos(LONG_DELAY_MS));
264 assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
265 break;
266 case awaitUntil:
267 // We shouldn't assume that nanoTime and currentTimeMillis
268 // use the same time source, so don't use nanoTime here.
269 java.util.Date delayedDate = delayedDate(timeoutMillis);
270 assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
271 assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
272 break;
273 default:
274 throw new UnsupportedOperationException();
275 }
276 } catch (InterruptedException ie) { threadUnexpectedException(ie); }
277 }
278
279 /**
280 * isHeldExclusively is false upon construction
281 */
282 public void testIsHeldExclusively() {
283 Mutex sync = new Mutex();
284 assertFalse(sync.isHeldExclusively());
285 }
286
287 /**
288 * acquiring released sync succeeds
289 */
290 public void testAcquire() {
291 Mutex sync = new Mutex();
292 sync.acquire();
293 assertTrue(sync.isHeldExclusively());
294 sync.release();
295 assertFalse(sync.isHeldExclusively());
296 }
297
298 /**
299 * tryAcquire on a released sync succeeds
300 */
301 public void testTryAcquire() {
302 Mutex sync = new Mutex();
303 assertTrue(sync.tryAcquire());
304 assertTrue(sync.isHeldExclusively());
305 sync.release();
306 assertFalse(sync.isHeldExclusively());
307 }
308
309 /**
310 * hasQueuedThreads reports whether there are waiting threads
311 */
312 public void testHasQueuedThreads() {
313 final Mutex sync = new Mutex();
314 assertFalse(sync.hasQueuedThreads());
315 sync.acquire();
316 Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
317 waitForQueuedThread(sync, t1);
318 assertTrue(sync.hasQueuedThreads());
319 Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
320 waitForQueuedThread(sync, t2);
321 assertTrue(sync.hasQueuedThreads());
322 t1.interrupt();
323 awaitTermination(t1);
324 assertTrue(sync.hasQueuedThreads());
325 sync.release();
326 awaitTermination(t2);
327 assertFalse(sync.hasQueuedThreads());
328 }
329
330 /**
331 * isQueued(null) throws NullPointerException
332 */
333 public void testIsQueuedNPE() {
334 final Mutex sync = new Mutex();
335 try {
336 sync.isQueued(null);
337 shouldThrow();
338 } catch (NullPointerException success) {}
339 }
340
341 /**
342 * isQueued reports whether a thread is queued
343 */
344 public void testIsQueued() {
345 final Mutex sync = new Mutex();
346 Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
347 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
348 assertFalse(sync.isQueued(t1));
349 assertFalse(sync.isQueued(t2));
350 sync.acquire();
351 t1.start();
352 waitForQueuedThread(sync, t1);
353 assertTrue(sync.isQueued(t1));
354 assertFalse(sync.isQueued(t2));
355 t2.start();
356 waitForQueuedThread(sync, t2);
357 assertTrue(sync.isQueued(t1));
358 assertTrue(sync.isQueued(t2));
359 t1.interrupt();
360 awaitTermination(t1);
361 assertFalse(sync.isQueued(t1));
362 assertTrue(sync.isQueued(t2));
363 sync.release();
364 awaitTermination(t2);
365 assertFalse(sync.isQueued(t1));
366 assertFalse(sync.isQueued(t2));
367 }
368
369 /**
370 * getFirstQueuedThread returns first waiting thread or null if none
371 */
372 public void testGetFirstQueuedThread() {
373 final Mutex sync = new Mutex();
374 assertNull(sync.getFirstQueuedThread());
375 sync.acquire();
376 Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
377 waitForQueuedThread(sync, t1);
378 assertEquals(t1, sync.getFirstQueuedThread());
379 Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
380 waitForQueuedThread(sync, t2);
381 assertEquals(t1, sync.getFirstQueuedThread());
382 t1.interrupt();
383 awaitTermination(t1);
384 assertEquals(t2, sync.getFirstQueuedThread());
385 sync.release();
386 awaitTermination(t2);
387 assertNull(sync.getFirstQueuedThread());
388 }
389
390 /**
391 * hasContended reports false if no thread has ever blocked, else true
392 */
393 public void testHasContended() {
394 final Mutex sync = new Mutex();
395 assertFalse(sync.hasContended());
396 sync.acquire();
397 assertFalse(sync.hasContended());
398 Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
399 waitForQueuedThread(sync, t1);
400 assertTrue(sync.hasContended());
401 Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
402 waitForQueuedThread(sync, t2);
403 assertTrue(sync.hasContended());
404 t1.interrupt();
405 awaitTermination(t1);
406 assertTrue(sync.hasContended());
407 sync.release();
408 awaitTermination(t2);
409 assertTrue(sync.hasContended());
410 }
411
412 /**
413 * getQueuedThreads returns all waiting threads
414 */
415 public void testGetQueuedThreads() {
416 final Mutex sync = new Mutex();
417 Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
418 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
419 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
420 sync.acquire();
421 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
422 t1.start();
423 waitForQueuedThread(sync, t1);
424 assertHasExclusiveQueuedThreads(sync, t1);
425 assertTrue(sync.getQueuedThreads().contains(t1));
426 assertFalse(sync.getQueuedThreads().contains(t2));
427 t2.start();
428 waitForQueuedThread(sync, t2);
429 assertHasExclusiveQueuedThreads(sync, t1, t2);
430 assertTrue(sync.getQueuedThreads().contains(t1));
431 assertTrue(sync.getQueuedThreads().contains(t2));
432 t1.interrupt();
433 awaitTermination(t1);
434 assertHasExclusiveQueuedThreads(sync, t2);
435 sync.release();
436 awaitTermination(t2);
437 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
438 }
439
440 /**
441 * getExclusiveQueuedThreads returns all exclusive waiting threads
442 */
443 public void testGetExclusiveQueuedThreads() {
444 final Mutex sync = new Mutex();
445 Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
446 Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
447 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
448 sync.acquire();
449 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
450 t1.start();
451 waitForQueuedThread(sync, t1);
452 assertHasExclusiveQueuedThreads(sync, t1);
453 assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
454 assertFalse(sync.getExclusiveQueuedThreads().contains(t2));
455 t2.start();
456 waitForQueuedThread(sync, t2);
457 assertHasExclusiveQueuedThreads(sync, t1, t2);
458 assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
459 assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
460 t1.interrupt();
461 awaitTermination(t1);
462 assertHasExclusiveQueuedThreads(sync, t2);
463 sync.release();
464 awaitTermination(t2);
465 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
466 }
467
468 /**
469 * getSharedQueuedThreads does not include exclusively waiting threads
470 */
471 public void testGetSharedQueuedThreads_Exclusive() {
472 final Mutex sync = new Mutex();
473 assertTrue(sync.getSharedQueuedThreads().isEmpty());
474 sync.acquire();
475 assertTrue(sync.getSharedQueuedThreads().isEmpty());
476 Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
477 waitForQueuedThread(sync, t1);
478 assertTrue(sync.getSharedQueuedThreads().isEmpty());
479 Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
480 waitForQueuedThread(sync, t2);
481 assertTrue(sync.getSharedQueuedThreads().isEmpty());
482 t1.interrupt();
483 awaitTermination(t1);
484 assertTrue(sync.getSharedQueuedThreads().isEmpty());
485 sync.release();
486 awaitTermination(t2);
487 assertTrue(sync.getSharedQueuedThreads().isEmpty());
488 }
489
490 /**
491 * getSharedQueuedThreads returns all shared waiting threads
492 */
493 public void testGetSharedQueuedThreads_Shared() {
494 final BooleanLatch l = new BooleanLatch();
495 assertHasSharedQueuedThreads(l, NO_THREADS);
496 Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
497 public void realRun() throws InterruptedException {
498 l.acquireSharedInterruptibly(0);
499 }});
500 waitForQueuedThread(l, t1);
501 assertHasSharedQueuedThreads(l, t1);
502 Thread t2 = newStartedThread(new CheckedRunnable() {
503 public void realRun() throws InterruptedException {
504 l.acquireSharedInterruptibly(0);
505 }});
506 waitForQueuedThread(l, t2);
507 assertHasSharedQueuedThreads(l, t1, t2);
508 t1.interrupt();
509 awaitTermination(t1);
510 assertHasSharedQueuedThreads(l, t2);
511 assertTrue(l.releaseShared(0));
512 awaitTermination(t2);
513 assertHasSharedQueuedThreads(l, NO_THREADS);
514 }
515
516 /**
517 * tryAcquireNanos is interruptible
518 */
519 public void testTryAcquireNanos_Interruptible() {
520 final Mutex sync = new Mutex();
521 sync.acquire();
522 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
523 public void realRun() throws InterruptedException {
524 sync.tryAcquireNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
525 }});
526
527 waitForQueuedThread(sync, t);
528 t.interrupt();
529 awaitTermination(t);
530 }
531
532 /**
533 * tryAcquire on exclusively held sync fails
534 */
535 public void testTryAcquireWhenSynced() {
536 final Mutex sync = new Mutex();
537 sync.acquire();
538 Thread t = newStartedThread(new CheckedRunnable() {
539 public void realRun() {
540 assertFalse(sync.tryAcquire());
541 }});
542
543 awaitTermination(t);
544 sync.release();
545 }
546
547 /**
548 * tryAcquireNanos on an exclusively held sync times out
549 */
550 public void testAcquireNanos_Timeout() {
551 final Mutex sync = new Mutex();
552 sync.acquire();
553 Thread t = newStartedThread(new CheckedRunnable() {
554 public void realRun() throws InterruptedException {
555 long startTime = System.nanoTime();
556 long nanos = MILLISECONDS.toNanos(timeoutMillis());
557 assertFalse(sync.tryAcquireNanos(nanos));
558 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
559 }});
560
561 awaitTermination(t);
562 sync.release();
563 }
564
565 /**
566 * getState is true when acquired and false when not
567 */
568 public void testGetState() {
569 final Mutex sync = new Mutex();
570 sync.acquire();
571 assertTrue(sync.isHeldExclusively());
572 sync.release();
573 assertFalse(sync.isHeldExclusively());
574
575 final BooleanLatch acquired = new BooleanLatch();
576 final BooleanLatch done = new BooleanLatch();
577 Thread t = newStartedThread(new CheckedRunnable() {
578 public void realRun() throws InterruptedException {
579 sync.acquire();
580 assertTrue(acquired.releaseShared(0));
581 done.acquireShared(0);
582 sync.release();
583 }});
584
585 acquired.acquireShared(0);
586 assertTrue(sync.isHeldExclusively());
587 assertTrue(done.releaseShared(0));
588 awaitTermination(t);
589 assertFalse(sync.isHeldExclusively());
590 }
591
592 /**
593 * acquireInterruptibly succeeds when released, else is interruptible
594 */
595 public void testAcquireInterruptibly() throws InterruptedException {
596 final Mutex sync = new Mutex();
597 final BooleanLatch threadStarted = new BooleanLatch();
598 sync.acquireInterruptibly();
599 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
600 public void realRun() throws InterruptedException {
601 assertTrue(threadStarted.releaseShared(0));
602 sync.acquireInterruptibly();
603 }});
604
605 threadStarted.acquireShared(0);
606 waitForQueuedThread(sync, t);
607 t.interrupt();
608 awaitTermination(t);
609 assertTrue(sync.isHeldExclusively());
610 }
611
612 /**
613 * owns is true for a condition created by sync else false
614 */
615 public void testOwns() {
616 final Mutex sync = new Mutex();
617 final ConditionObject c = sync.newCondition();
618 final Mutex sync2 = new Mutex();
619 assertTrue(sync.owns(c));
620 assertFalse(sync2.owns(c));
621 }
622
623 /**
624 * Calling await without holding sync throws IllegalMonitorStateException
625 */
626 public void testAwait_IMSE() {
627 final Mutex sync = new Mutex();
628 final ConditionObject c = sync.newCondition();
629 for (AwaitMethod awaitMethod : AwaitMethod.values()) {
630 long startTime = System.nanoTime();
631 try {
632 await(c, awaitMethod);
633 shouldThrow();
634 } catch (IllegalMonitorStateException success) {
635 } catch (InterruptedException e) { threadUnexpectedException(e); }
636 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
637 }
638 }
639
640 /**
641 * Calling signal without holding sync throws IllegalMonitorStateException
642 */
643 public void testSignal_IMSE() {
644 final Mutex sync = new Mutex();
645 final ConditionObject c = sync.newCondition();
646 try {
647 c.signal();
648 shouldThrow();
649 } catch (IllegalMonitorStateException success) {}
650 assertHasWaitersUnlocked(sync, c, NO_THREADS);
651 }
652
653 /**
654 * Calling signalAll without holding sync throws IllegalMonitorStateException
655 */
656 public void testSignalAll_IMSE() {
657 final Mutex sync = new Mutex();
658 final ConditionObject c = sync.newCondition();
659 try {
660 c.signalAll();
661 shouldThrow();
662 } catch (IllegalMonitorStateException success) {}
663 }
664
665 /**
666 * await/awaitNanos/awaitUntil without a signal times out
667 */
668 public void testAwaitTimed_Timeout() { testAwait_Timeout(AwaitMethod.awaitTimed); }
669 public void testAwaitNanos_Timeout() { testAwait_Timeout(AwaitMethod.awaitNanos); }
670 public void testAwaitUntil_Timeout() { testAwait_Timeout(AwaitMethod.awaitUntil); }
671 public void testAwait_Timeout(AwaitMethod awaitMethod) {
672 final Mutex sync = new Mutex();
673 final ConditionObject c = sync.newCondition();
674 sync.acquire();
675 assertAwaitTimesOut(c, awaitMethod);
676 sync.release();
677 }
678
679 /**
680 * await/awaitNanos/awaitUntil returns when signalled
681 */
682 public void testSignal_await() { testSignal(AwaitMethod.await); }
683 public void testSignal_awaitTimed() { testSignal(AwaitMethod.awaitTimed); }
684 public void testSignal_awaitNanos() { testSignal(AwaitMethod.awaitNanos); }
685 public void testSignal_awaitUntil() { testSignal(AwaitMethod.awaitUntil); }
686 public void testSignal(final AwaitMethod awaitMethod) {
687 final Mutex sync = new Mutex();
688 final ConditionObject c = sync.newCondition();
689 final BooleanLatch acquired = new BooleanLatch();
690 Thread t = newStartedThread(new CheckedRunnable() {
691 public void realRun() throws InterruptedException {
692 sync.acquire();
693 assertTrue(acquired.releaseShared(0));
694 await(c, awaitMethod);
695 sync.release();
696 }});
697
698 acquired.acquireShared(0);
699 sync.acquire();
700 assertHasWaitersLocked(sync, c, t);
701 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
702 c.signal();
703 assertHasWaitersLocked(sync, c, NO_THREADS);
704 assertHasExclusiveQueuedThreads(sync, t);
705 sync.release();
706 awaitTermination(t);
707 }
708
709 /**
710 * hasWaiters(null) throws NullPointerException
711 */
712 public void testHasWaitersNPE() {
713 final Mutex sync = new Mutex();
714 try {
715 sync.hasWaiters(null);
716 shouldThrow();
717 } catch (NullPointerException success) {}
718 }
719
720 /**
721 * getWaitQueueLength(null) throws NullPointerException
722 */
723 public void testGetWaitQueueLengthNPE() {
724 final Mutex sync = new Mutex();
725 try {
726 sync.getWaitQueueLength(null);
727 shouldThrow();
728 } catch (NullPointerException success) {}
729 }
730
731 /**
732 * getWaitingThreads(null) throws NullPointerException
733 */
734 public void testGetWaitingThreadsNPE() {
735 final Mutex sync = new Mutex();
736 try {
737 sync.getWaitingThreads(null);
738 shouldThrow();
739 } catch (NullPointerException success) {}
740 }
741
742 /**
743 * hasWaiters throws IllegalArgumentException if not owned
744 */
745 public void testHasWaitersIAE() {
746 final Mutex sync = new Mutex();
747 final ConditionObject c = sync.newCondition();
748 final Mutex sync2 = new Mutex();
749 try {
750 sync2.hasWaiters(c);
751 shouldThrow();
752 } catch (IllegalArgumentException success) {}
753 assertHasWaitersUnlocked(sync, c, NO_THREADS);
754 }
755
756 /**
757 * hasWaiters throws IllegalMonitorStateException if not synced
758 */
759 public void testHasWaitersIMSE() {
760 final Mutex sync = new Mutex();
761 final ConditionObject c = sync.newCondition();
762 try {
763 sync.hasWaiters(c);
764 shouldThrow();
765 } catch (IllegalMonitorStateException success) {}
766 assertHasWaitersUnlocked(sync, c, NO_THREADS);
767 }
768
769 /**
770 * getWaitQueueLength throws IllegalArgumentException if not owned
771 */
772 public void testGetWaitQueueLengthIAE() {
773 final Mutex sync = new Mutex();
774 final ConditionObject c = sync.newCondition();
775 final Mutex sync2 = new Mutex();
776 try {
777 sync2.getWaitQueueLength(c);
778 shouldThrow();
779 } catch (IllegalArgumentException success) {}
780 assertHasWaitersUnlocked(sync, c, NO_THREADS);
781 }
782
783 /**
784 * getWaitQueueLength throws IllegalMonitorStateException if not synced
785 */
786 public void testGetWaitQueueLengthIMSE() {
787 final Mutex sync = new Mutex();
788 final ConditionObject c = sync.newCondition();
789 try {
790 sync.getWaitQueueLength(c);
791 shouldThrow();
792 } catch (IllegalMonitorStateException success) {}
793 assertHasWaitersUnlocked(sync, c, NO_THREADS);
794 }
795
796 /**
797 * getWaitingThreads throws IllegalArgumentException if not owned
798 */
799 public void testGetWaitingThreadsIAE() {
800 final Mutex sync = new Mutex();
801 final ConditionObject c = sync.newCondition();
802 final Mutex sync2 = new Mutex();
803 try {
804 sync2.getWaitingThreads(c);
805 shouldThrow();
806 } catch (IllegalArgumentException success) {}
807 assertHasWaitersUnlocked(sync, c, NO_THREADS);
808 }
809
810 /**
811 * getWaitingThreads throws IllegalMonitorStateException if not synced
812 */
813 public void testGetWaitingThreadsIMSE() {
814 final Mutex sync = new Mutex();
815 final ConditionObject c = sync.newCondition();
816 try {
817 sync.getWaitingThreads(c);
818 shouldThrow();
819 } catch (IllegalMonitorStateException success) {}
820 assertHasWaitersUnlocked(sync, c, NO_THREADS);
821 }
822
823 /**
824 * hasWaiters returns true when a thread is waiting, else false
825 */
826 public void testHasWaiters() {
827 final Mutex sync = new Mutex();
828 final ConditionObject c = sync.newCondition();
829 final BooleanLatch acquired = new BooleanLatch();
830 Thread t = newStartedThread(new CheckedRunnable() {
831 public void realRun() throws InterruptedException {
832 sync.acquire();
833 assertHasWaitersLocked(sync, c, NO_THREADS);
834 assertFalse(sync.hasWaiters(c));
835 assertTrue(acquired.releaseShared(0));
836 c.await();
837 sync.release();
838 }});
839
840 acquired.acquireShared(0);
841 sync.acquire();
842 assertHasWaitersLocked(sync, c, t);
843 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
844 assertTrue(sync.hasWaiters(c));
845 c.signal();
846 assertHasWaitersLocked(sync, c, NO_THREADS);
847 assertHasExclusiveQueuedThreads(sync, t);
848 assertFalse(sync.hasWaiters(c));
849 sync.release();
850
851 awaitTermination(t);
852 assertHasWaitersUnlocked(sync, c, NO_THREADS);
853 }
854
855 /**
856 * getWaitQueueLength returns number of waiting threads
857 */
858 public void testGetWaitQueueLength() {
859 final Mutex sync = new Mutex();
860 final ConditionObject c = sync.newCondition();
861 final BooleanLatch acquired1 = new BooleanLatch();
862 final BooleanLatch acquired2 = new BooleanLatch();
863 final Thread t1 = newStartedThread(new CheckedRunnable() {
864 public void realRun() throws InterruptedException {
865 sync.acquire();
866 assertHasWaitersLocked(sync, c, NO_THREADS);
867 assertEquals(0, sync.getWaitQueueLength(c));
868 assertTrue(acquired1.releaseShared(0));
869 c.await();
870 sync.release();
871 }});
872 acquired1.acquireShared(0);
873 sync.acquire();
874 assertHasWaitersLocked(sync, c, t1);
875 assertEquals(1, sync.getWaitQueueLength(c));
876 sync.release();
877
878 final Thread t2 = newStartedThread(new CheckedRunnable() {
879 public void realRun() throws InterruptedException {
880 sync.acquire();
881 assertHasWaitersLocked(sync, c, t1);
882 assertEquals(1, sync.getWaitQueueLength(c));
883 assertTrue(acquired2.releaseShared(0));
884 c.await();
885 sync.release();
886 }});
887 acquired2.acquireShared(0);
888 sync.acquire();
889 assertHasWaitersLocked(sync, c, t1, t2);
890 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
891 assertEquals(2, sync.getWaitQueueLength(c));
892 c.signalAll();
893 assertHasWaitersLocked(sync, c, NO_THREADS);
894 assertHasExclusiveQueuedThreads(sync, t1, t2);
895 assertEquals(0, sync.getWaitQueueLength(c));
896 sync.release();
897
898 awaitTermination(t1);
899 awaitTermination(t2);
900 assertHasWaitersUnlocked(sync, c, NO_THREADS);
901 }
902
903 /**
904 * getWaitingThreads returns only and all waiting threads
905 */
906 public void testGetWaitingThreads() {
907 final Mutex sync = new Mutex();
908 final ConditionObject c = sync.newCondition();
909 final BooleanLatch acquired1 = new BooleanLatch();
910 final BooleanLatch acquired2 = new BooleanLatch();
911 final Thread t1 = new Thread(new CheckedRunnable() {
912 public void realRun() throws InterruptedException {
913 sync.acquire();
914 assertHasWaitersLocked(sync, c, NO_THREADS);
915 assertTrue(sync.getWaitingThreads(c).isEmpty());
916 assertTrue(acquired1.releaseShared(0));
917 c.await();
918 sync.release();
919 }});
920
921 final Thread t2 = new Thread(new CheckedRunnable() {
922 public void realRun() throws InterruptedException {
923 sync.acquire();
924 assertHasWaitersLocked(sync, c, t1);
925 assertTrue(sync.getWaitingThreads(c).contains(t1));
926 assertFalse(sync.getWaitingThreads(c).isEmpty());
927 assertEquals(1, sync.getWaitingThreads(c).size());
928 assertTrue(acquired2.releaseShared(0));
929 c.await();
930 sync.release();
931 }});
932
933 sync.acquire();
934 assertHasWaitersLocked(sync, c, NO_THREADS);
935 assertFalse(sync.getWaitingThreads(c).contains(t1));
936 assertFalse(sync.getWaitingThreads(c).contains(t2));
937 assertTrue(sync.getWaitingThreads(c).isEmpty());
938 assertEquals(0, sync.getWaitingThreads(c).size());
939 sync.release();
940
941 t1.start();
942 acquired1.acquireShared(0);
943 sync.acquire();
944 assertHasWaitersLocked(sync, c, t1);
945 assertTrue(sync.getWaitingThreads(c).contains(t1));
946 assertFalse(sync.getWaitingThreads(c).contains(t2));
947 assertFalse(sync.getWaitingThreads(c).isEmpty());
948 assertEquals(1, sync.getWaitingThreads(c).size());
949 sync.release();
950
951 t2.start();
952 acquired2.acquireShared(0);
953 sync.acquire();
954 assertHasWaitersLocked(sync, c, t1, t2);
955 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
956 assertTrue(sync.getWaitingThreads(c).contains(t1));
957 assertTrue(sync.getWaitingThreads(c).contains(t2));
958 assertFalse(sync.getWaitingThreads(c).isEmpty());
959 assertEquals(2, sync.getWaitingThreads(c).size());
960 c.signalAll();
961 assertHasWaitersLocked(sync, c, NO_THREADS);
962 assertHasExclusiveQueuedThreads(sync, t1, t2);
963 assertFalse(sync.getWaitingThreads(c).contains(t1));
964 assertFalse(sync.getWaitingThreads(c).contains(t2));
965 assertTrue(sync.getWaitingThreads(c).isEmpty());
966 assertEquals(0, sync.getWaitingThreads(c).size());
967 sync.release();
968
969 awaitTermination(t1);
970 awaitTermination(t2);
971 assertHasWaitersUnlocked(sync, c, NO_THREADS);
972 }
973
974 /**
975 * awaitUninterruptibly is uninterruptible
976 */
977 public void testAwaitUninterruptibly() {
978 final Mutex sync = new Mutex();
979 final ConditionObject condition = sync.newCondition();
980 final BooleanLatch pleaseInterrupt = new BooleanLatch();
981 Thread t = newStartedThread(new CheckedRunnable() {
982 public void realRun() {
983 sync.acquire();
984 assertTrue(pleaseInterrupt.releaseShared(0));
985 condition.awaitUninterruptibly();
986 assertTrue(Thread.interrupted());
987 assertHasWaitersLocked(sync, condition, NO_THREADS);
988 sync.release();
989 }});
990
991 pleaseInterrupt.acquireShared(0);
992 sync.acquire();
993 assertHasWaitersLocked(sync, condition, t);
994 sync.release();
995 t.interrupt();
996 assertHasWaitersUnlocked(sync, condition, t);
997 assertThreadBlocks(t, Thread.State.WAITING);
998 sync.acquire();
999 assertHasWaitersLocked(sync, condition, t);
1000 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
1001 condition.signal();
1002 assertHasWaitersLocked(sync, condition, NO_THREADS);
1003 assertHasExclusiveQueuedThreads(sync, t);
1004 sync.release();
1005 awaitTermination(t);
1006 }
1007
1008 /**
1009 * await/awaitNanos/awaitUntil is interruptible
1010 */
1011 public void testInterruptible_await() { testInterruptible(AwaitMethod.await); }
1012 public void testInterruptible_awaitTimed() { testInterruptible(AwaitMethod.awaitTimed); }
1013 public void testInterruptible_awaitNanos() { testInterruptible(AwaitMethod.awaitNanos); }
1014 public void testInterruptible_awaitUntil() { testInterruptible(AwaitMethod.awaitUntil); }
1015 public void testInterruptible(final AwaitMethod awaitMethod) {
1016 final Mutex sync = new Mutex();
1017 final ConditionObject c = sync.newCondition();
1018 final BooleanLatch pleaseInterrupt = new BooleanLatch();
1019 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1020 public void realRun() throws InterruptedException {
1021 sync.acquire();
1022 assertTrue(pleaseInterrupt.releaseShared(0));
1023 await(c, awaitMethod);
1024 }});
1025
1026 pleaseInterrupt.acquireShared(0);
1027 t.interrupt();
1028 awaitTermination(t);
1029 }
1030
1031 /**
1032 * signalAll wakes up all threads
1033 */
1034 public void testSignalAll_await() { testSignalAll(AwaitMethod.await); }
1035 public void testSignalAll_awaitTimed() { testSignalAll(AwaitMethod.awaitTimed); }
1036 public void testSignalAll_awaitNanos() { testSignalAll(AwaitMethod.awaitNanos); }
1037 public void testSignalAll_awaitUntil() { testSignalAll(AwaitMethod.awaitUntil); }
1038 public void testSignalAll(final AwaitMethod awaitMethod) {
1039 final Mutex sync = new Mutex();
1040 final ConditionObject c = sync.newCondition();
1041 final BooleanLatch acquired1 = new BooleanLatch();
1042 final BooleanLatch acquired2 = new BooleanLatch();
1043 Thread t1 = newStartedThread(new CheckedRunnable() {
1044 public void realRun() throws InterruptedException {
1045 sync.acquire();
1046 acquired1.releaseShared(0);
1047 await(c, awaitMethod);
1048 sync.release();
1049 }});
1050
1051 Thread t2 = newStartedThread(new CheckedRunnable() {
1052 public void realRun() throws InterruptedException {
1053 sync.acquire();
1054 acquired2.releaseShared(0);
1055 await(c, awaitMethod);
1056 sync.release();
1057 }});
1058
1059 acquired1.acquireShared(0);
1060 acquired2.acquireShared(0);
1061 sync.acquire();
1062 assertHasWaitersLocked(sync, c, t1, t2);
1063 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
1064 c.signalAll();
1065 assertHasWaitersLocked(sync, c, NO_THREADS);
1066 assertHasExclusiveQueuedThreads(sync, t1, t2);
1067 sync.release();
1068 awaitTermination(t1);
1069 awaitTermination(t2);
1070 }
1071
1072 /**
1073 * toString indicates current state
1074 */
1075 public void testToString() {
1076 Mutex sync = new Mutex();
1077 assertTrue(sync.toString().contains("State = " + Mutex.UNLOCKED));
1078 sync.acquire();
1079 assertTrue(sync.toString().contains("State = " + Mutex.LOCKED));
1080 }
1081
1082 /**
1083 * A serialized AQS deserializes with current state, but no queued threads
1084 */
1085 public void testSerialization() {
1086 Mutex sync = new Mutex();
1087 assertFalse(serialClone(sync).isHeldExclusively());
1088 sync.acquire();
1089 Thread t = newStartedThread(new InterruptedSyncRunnable(sync));
1090 waitForQueuedThread(sync, t);
1091 assertTrue(sync.isHeldExclusively());
1092
1093 Mutex clone = serialClone(sync);
1094 assertTrue(clone.isHeldExclusively());
1095 assertHasExclusiveQueuedThreads(sync, t);
1096 assertHasExclusiveQueuedThreads(clone, NO_THREADS);
1097 t.interrupt();
1098 awaitTermination(t);
1099 sync.release();
1100 assertFalse(sync.isHeldExclusively());
1101 assertTrue(clone.isHeldExclusively());
1102 assertHasExclusiveQueuedThreads(sync, NO_THREADS);
1103 assertHasExclusiveQueuedThreads(clone, NO_THREADS);
1104 }
1105
1106 /**
1107 * tryReleaseShared setting state changes getState
1108 */
1109 public void testGetStateWithReleaseShared() {
1110 final BooleanLatch l = new BooleanLatch();
1111 assertFalse(l.isSignalled());
1112 assertTrue(l.releaseShared(0));
1113 assertTrue(l.isSignalled());
1114 }
1115
1116 /**
1117 * releaseShared has no effect when already signalled
1118 */
1119 public void testReleaseShared() {
1120 final BooleanLatch l = new BooleanLatch();
1121 assertFalse(l.isSignalled());
1122 assertTrue(l.releaseShared(0));
1123 assertTrue(l.isSignalled());
1124 assertTrue(l.releaseShared(0));
1125 assertTrue(l.isSignalled());
1126 }
1127
1128 /**
1129 * acquireSharedInterruptibly returns after release, but not before
1130 */
1131 public void testAcquireSharedInterruptibly() {
1132 final BooleanLatch l = new BooleanLatch();
1133
1134 Thread t = newStartedThread(new CheckedRunnable() {
1135 public void realRun() throws InterruptedException {
1136 assertFalse(l.isSignalled());
1137 l.acquireSharedInterruptibly(0);
1138 assertTrue(l.isSignalled());
1139 l.acquireSharedInterruptibly(0);
1140 assertTrue(l.isSignalled());
1141 }});
1142
1143 waitForQueuedThread(l, t);
1144 assertFalse(l.isSignalled());
1145 assertThreadBlocks(t, Thread.State.WAITING);
1146 assertHasSharedQueuedThreads(l, t);
1147 assertTrue(l.releaseShared(0));
1148 assertTrue(l.isSignalled());
1149 awaitTermination(t);
1150 }
1151
1152 /**
1153 * tryAcquireSharedNanos returns after release, but not before
1154 */
1155 public void testTryAcquireSharedNanos() {
1156 final BooleanLatch l = new BooleanLatch();
1157
1158 Thread t = newStartedThread(new CheckedRunnable() {
1159 public void realRun() throws InterruptedException {
1160 assertFalse(l.isSignalled());
1161 long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
1162 assertTrue(l.tryAcquireSharedNanos(0, nanos));
1163 assertTrue(l.isSignalled());
1164 assertTrue(l.tryAcquireSharedNanos(0, nanos));
1165 assertTrue(l.isSignalled());
1166 }});
1167
1168 waitForQueuedThread(l, t);
1169 assertFalse(l.isSignalled());
1170 assertThreadBlocks(t, Thread.State.TIMED_WAITING);
1171 assertTrue(l.releaseShared(0));
1172 assertTrue(l.isSignalled());
1173 awaitTermination(t);
1174 }
1175
1176 /**
1177 * acquireSharedInterruptibly is interruptible
1178 */
1179 public void testAcquireSharedInterruptibly_Interruptible() {
1180 final BooleanLatch l = new BooleanLatch();
1181 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1182 public void realRun() throws InterruptedException {
1183 assertFalse(l.isSignalled());
1184 l.acquireSharedInterruptibly(0);
1185 }});
1186
1187 waitForQueuedThread(l, t);
1188 assertFalse(l.isSignalled());
1189 t.interrupt();
1190 awaitTermination(t);
1191 assertFalse(l.isSignalled());
1192 }
1193
1194 /**
1195 * tryAcquireSharedNanos is interruptible
1196 */
1197 public void testTryAcquireSharedNanos_Interruptible() {
1198 final BooleanLatch l = new BooleanLatch();
1199 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1200 public void realRun() throws InterruptedException {
1201 assertFalse(l.isSignalled());
1202 long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
1203 l.tryAcquireSharedNanos(0, nanos);
1204 }});
1205
1206 waitForQueuedThread(l, t);
1207 assertFalse(l.isSignalled());
1208 t.interrupt();
1209 awaitTermination(t);
1210 assertFalse(l.isSignalled());
1211 }
1212
1213 /**
1214 * tryAcquireSharedNanos times out if not released before timeout
1215 */
1216 public void testTryAcquireSharedNanos_Timeout() {
1217 final BooleanLatch l = new BooleanLatch();
1218 final BooleanLatch observedQueued = new BooleanLatch();
1219 Thread t = newStartedThread(new CheckedRunnable() {
1220 public void realRun() throws InterruptedException {
1221 assertFalse(l.isSignalled());
1222 for (long millis = timeoutMillis();
1223 !observedQueued.isSignalled();
1224 millis *= 2) {
1225 long nanos = MILLISECONDS.toNanos(millis);
1226 long startTime = System.nanoTime();
1227 assertFalse(l.tryAcquireSharedNanos(0, nanos));
1228 assertTrue(millisElapsedSince(startTime) >= millis);
1229 }
1230 assertFalse(l.isSignalled());
1231 }});
1232
1233 waitForQueuedThread(l, t);
1234 observedQueued.releaseShared(0);
1235 assertFalse(l.isSignalled());
1236 awaitTermination(t);
1237 assertFalse(l.isSignalled());
1238 }
1239
1240 /**
1241 * awaitNanos/timed await with 0 wait times out immediately
1242 */
1243 public void testAwait_Zero() throws InterruptedException {
1244 final Mutex sync = new Mutex();
1245 final ConditionObject c = sync.newCondition();
1246 sync.acquire();
1247 assertTrue(c.awaitNanos(0L) <= 0);
1248 assertFalse(c.await(0L, NANOSECONDS));
1249 sync.release();
1250 }
1251
1252 /**
1253 * awaitNanos/timed await with maximum negative wait times does not underflow
1254 */
1255 public void testAwait_NegativeInfinity() throws InterruptedException {
1256 final Mutex sync = new Mutex();
1257 final ConditionObject c = sync.newCondition();
1258 sync.acquire();
1259 assertTrue(c.awaitNanos(Long.MIN_VALUE) <= 0);
1260 assertFalse(c.await(Long.MIN_VALUE, NANOSECONDS));
1261 sync.release();
1262 }
1263
1264 /**
1265 * Disabled demo test for (unfixed as of 2017-11)
1266 * JDK-8191483: AbstractQueuedSynchronizer cancel/cancel race
1267 * ant -Djsr166.tckTestClass=AbstractQueuedSynchronizerTest -Djsr166.methodFilter=testCancelCancelRace -Djsr166.runsPerTest=100 tck
1268 */
1269 public void DISABLED_testCancelCancelRace() throws InterruptedException {
1270 class Sync extends AbstractQueuedSynchronizer {
1271 protected boolean tryAcquire(int acquires) {
1272 return !hasQueuedPredecessors() && compareAndSetState(0, 1);
1273 }
1274 protected boolean tryRelease(int releases) {
1275 return compareAndSetState(1, 0);
1276 }
1277 }
1278
1279 Sync s = new Sync();
1280 s.acquire(1); // acquire to force other threads to enqueue
1281
1282 // try to trigger double cancel race with two background threads
1283 ArrayList<Thread> threads = new ArrayList<>();
1284 Runnable failedAcquire = () -> {
1285 try {
1286 s.acquireInterruptibly(1);
1287 shouldThrow();
1288 } catch (InterruptedException expected) {}
1289 };
1290 for (int i = 0; i < 2; i++) {
1291 Thread thread = new Thread(failedAcquire);
1292 thread.start();
1293 threads.add(thread);
1294 }
1295 Thread.sleep(100);
1296 for (Thread thread : threads) thread.interrupt();
1297 for (Thread thread : threads) awaitTermination(thread);
1298
1299 s.release(1);
1300
1301 // no one holds lock now, we should be able to acquire
1302 if (!s.tryAcquire(1))
1303 throw new RuntimeException(
1304 String.format(
1305 "Broken: hasQueuedPredecessors=%s hasQueuedThreads=%s queueLength=%d firstQueuedThread=%s",
1306 s.hasQueuedPredecessors(),
1307 s.hasQueuedThreads(),
1308 s.getQueueLength(),
1309 s.getFirstQueuedThread()));
1310 }
1311
1312 /**
1313 * Tests scenario for
1314 * JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw
1315 */
1316 public void testInterruptedFailingAcquire() throws InterruptedException {
1317 final RuntimeException ex = new RuntimeException();
1318
1319 // A synchronizer only offering a choice of failure modes
1320 class Sync extends AbstractQueuedSynchronizer {
1321 boolean pleaseThrow;
1322 @Override protected boolean tryAcquire(int ignored) {
1323 if (pleaseThrow) throw ex;
1324 return false;
1325 }
1326 @Override protected int tryAcquireShared(int ignored) {
1327 if (pleaseThrow) throw ex;
1328 return -1;
1329 }
1330 @Override protected boolean tryRelease(int ignored) {
1331 return true;
1332 }
1333 @Override protected boolean tryReleaseShared(int ignored) {
1334 return true;
1335 }
1336 }
1337
1338 final Sync s = new Sync();
1339
1340 final Thread thread = newStartedThread(new CheckedRunnable() {
1341 public void realRun() {
1342 try {
1343 if (ThreadLocalRandom.current().nextBoolean())
1344 s.acquire(1);
1345 else
1346 s.acquireShared(1);
1347 shouldThrow();
1348 } catch (Throwable t) {
1349 assertSame(ex, t);
1350 assertTrue(Thread.interrupted());
1351 }
1352 }});
1353 waitForThreadToEnterWaitState(thread);
1354 assertSame(thread, s.getFirstQueuedThread());
1355 assertTrue(s.hasQueuedPredecessors());
1356 assertTrue(s.hasQueuedThreads());
1357 assertEquals(1, s.getQueueLength());
1358
1359 s.pleaseThrow = true;
1360 thread.interrupt();
1361 s.release(1);
1362 awaitTermination(thread);
1363 }
1364
1365 }

dl@cs.oswego.edu
ViewVC Help
Powered by ViewVC 1.1.27