ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java
Revision: 1.43
Committed: Mon Nov 27 23:06:53 2017 UTC (6 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.42: +54 -0 lines
Log Message:
JDK-8191937: Lost interrupt in AbstractQueuedSynchronizer when tryAcquire methods throw

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