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