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