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