ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java
Revision: 1.53
Committed: Fri Aug 16 02:32:26 2019 UTC (4 years, 8 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.52: +16 -2 lines
Log Message:
check that try-acquire methods can are not called again if they fail once

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