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