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