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.concurrent.locks.*; 13import java.util.concurrent.*; 14import java.util.*; 15import java.io.*; 16 17public class ReentrantLockTest 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(ReentrantLockTest.class); 23 } 24 25 /** 26 * A runnable calling lockInterruptibly 27 */ 28 class InterruptibleLockRunnable implements Runnable { 29 final ReentrantLock lock; 30 InterruptibleLockRunnable(ReentrantLock l) { lock = l; } 31 public void run() { 32 try { 33 lock.lockInterruptibly(); 34 } catch(InterruptedException success){} 35 } 36 } 37 38 39 /** 40 * A runnable calling lockInterruptibly that expects to be 41 * interrupted 42 */ 43 class InterruptedLockRunnable implements Runnable { 44 final ReentrantLock lock; 45 InterruptedLockRunnable(ReentrantLock l) { lock = l; } 46 public void run() { 47 try { 48 lock.lockInterruptibly(); 49 threadShouldThrow(); 50 } catch(InterruptedException success){} 51 } 52 } 53 54 /** 55 * Subclass to expose protected methods 56 */ 57 static class PublicReentrantLock extends ReentrantLock { 58 PublicReentrantLock() { super(); } 59 public Collection<Thread> getQueuedThreads() { 60 return super.getQueuedThreads(); 61 } 62 public Collection<Thread> getWaitingThreads(Condition c) { 63 return super.getWaitingThreads(c); 64 } 65 66 67 } 68 69 /** 70 * Constructor sets given fairness 71 */ 72 public void testConstructor() { 73 ReentrantLock rl = new ReentrantLock(); 74 assertFalse(rl.isFair()); 75 ReentrantLock r2 = new ReentrantLock(true); 76 assertTrue(r2.isFair()); 77 } 78 79 /** 80 * locking an unlocked lock succeeds 81 */ 82 public void testLock() { 83 ReentrantLock rl = new ReentrantLock(); 84 rl.lock(); 85 assertTrue(rl.isLocked()); 86 rl.unlock(); 87 } 88 89 /** 90 * locking an unlocked fair lock succeeds 91 */ 92 public void testFairLock() { 93 ReentrantLock rl = new ReentrantLock(true); 94 rl.lock(); 95 assertTrue(rl.isLocked()); 96 rl.unlock(); 97 } 98 99 /** 100 * Unlocking an unlocked lock throws IllegalMonitorStateException 101 */ 102 public void testUnlock_IllegalMonitorStateException() { 103 ReentrantLock rl = new ReentrantLock(); 104 try { 105 rl.unlock(); 106 shouldThrow(); 107 108 } catch(IllegalMonitorStateException success){} 109 } 110 111 /** 112 * tryLock on an unlocked lock succeeds 113 */ 114 public void testTryLock() { 115 ReentrantLock rl = new ReentrantLock(); 116 assertTrue(rl.tryLock()); 117 assertTrue(rl.isLocked()); 118 rl.unlock(); 119 } 120 121 122 /** 123 * hasQueuedThreads reports whether there are waiting threads 124 */ 125 public void testhasQueuedThreads() { 126 final ReentrantLock lock = new ReentrantLock(); 127 Thread t1 = new Thread(new InterruptedLockRunnable(lock)); 128 Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); 129 try { 130 assertFalse(lock.hasQueuedThreads()); 131 lock.lock(); 132 t1.start(); 133 Thread.sleep(SHORT_DELAY_MS); 134 assertTrue(lock.hasQueuedThreads()); 135 t2.start(); 136 Thread.sleep(SHORT_DELAY_MS); 137 assertTrue(lock.hasQueuedThreads()); 138 t1.interrupt(); 139 Thread.sleep(SHORT_DELAY_MS); 140 assertTrue(lock.hasQueuedThreads()); 141 lock.unlock(); 142 Thread.sleep(SHORT_DELAY_MS); 143 assertFalse(lock.hasQueuedThreads()); 144 t1.join(); 145 t2.join(); 146 } catch(Exception e){ 147 unexpectedException(); 148 } 149 } 150 151 /** 152 * getQueueLength reports number of waiting threads 153 */ 154 public void testGetQueueLength() { 155 final ReentrantLock lock = new ReentrantLock(); 156 Thread t1 = new Thread(new InterruptedLockRunnable(lock)); 157 Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); 158 try { 159 assertEquals(0, lock.getQueueLength()); 160 lock.lock(); 161 t1.start(); 162 Thread.sleep(SHORT_DELAY_MS); 163 assertEquals(1, lock.getQueueLength()); 164 t2.start(); 165 Thread.sleep(SHORT_DELAY_MS); 166 assertEquals(2, lock.getQueueLength()); 167 t1.interrupt(); 168 Thread.sleep(SHORT_DELAY_MS); 169 assertEquals(1, lock.getQueueLength()); 170 lock.unlock(); 171 Thread.sleep(SHORT_DELAY_MS); 172 assertEquals(0, lock.getQueueLength()); 173 t1.join(); 174 t2.join(); 175 } catch(Exception e){ 176 unexpectedException(); 177 } 178 } 179 180 /** 181 * getQueueLength reports number of waiting threads 182 */ 183 public void testGetQueueLength_fair() { 184 final ReentrantLock lock = new ReentrantLock(true); 185 Thread t1 = new Thread(new InterruptedLockRunnable(lock)); 186 Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); 187 try { 188 assertEquals(0, lock.getQueueLength()); 189 lock.lock(); 190 t1.start(); 191 Thread.sleep(SHORT_DELAY_MS); 192 assertEquals(1, lock.getQueueLength()); 193 t2.start(); 194 Thread.sleep(SHORT_DELAY_MS); 195 assertEquals(2, lock.getQueueLength()); 196 t1.interrupt(); 197 Thread.sleep(SHORT_DELAY_MS); 198 assertEquals(1, lock.getQueueLength()); 199 lock.unlock(); 200 Thread.sleep(SHORT_DELAY_MS); 201 assertEquals(0, lock.getQueueLength()); 202 t1.join(); 203 t2.join(); 204 } catch(Exception e){ 205 unexpectedException(); 206 } 207 } 208 209 /** 210 * hasQueuedThread(null) throws NPE 211 */ 212 public void testHasQueuedThreadNPE() { 213 final ReentrantLock sync = new ReentrantLock(); 214 try { 215 sync.hasQueuedThread(null); 216 shouldThrow(); 217 } catch (NullPointerException success) { 218 } 219 } 220 221 /** 222 * hasQueuedThread reports whether a thread is queued. 223 */ 224 public void testHasQueuedThread() { 225 final ReentrantLock sync = new ReentrantLock(); 226 Thread t1 = new Thread(new InterruptedLockRunnable(sync)); 227 Thread t2 = new Thread(new InterruptibleLockRunnable(sync)); 228 try { 229 assertFalse(sync.hasQueuedThread(t1)); 230 assertFalse(sync.hasQueuedThread(t2)); 231 sync.lock(); 232 t1.start(); 233 Thread.sleep(SHORT_DELAY_MS); 234 assertTrue(sync.hasQueuedThread(t1)); 235 t2.start(); 236 Thread.sleep(SHORT_DELAY_MS); 237 assertTrue(sync.hasQueuedThread(t1)); 238 assertTrue(sync.hasQueuedThread(t2)); 239 t1.interrupt(); 240 Thread.sleep(SHORT_DELAY_MS); 241 assertFalse(sync.hasQueuedThread(t1)); 242 assertTrue(sync.hasQueuedThread(t2)); 243 sync.unlock(); 244 Thread.sleep(SHORT_DELAY_MS); 245 assertFalse(sync.hasQueuedThread(t1)); 246 Thread.sleep(SHORT_DELAY_MS); 247 assertFalse(sync.hasQueuedThread(t2)); 248 t1.join(); 249 t2.join(); 250 } catch(Exception e){ 251 unexpectedException(); 252 } 253 } 254 255 256 /** 257 * getQueuedThreads includes waiting threads 258 */ 259 public void testGetQueuedThreads() { 260 final PublicReentrantLock lock = new PublicReentrantLock(); 261 Thread t1 = new Thread(new InterruptedLockRunnable(lock)); 262 Thread t2 = new Thread(new InterruptibleLockRunnable(lock)); 263 try { 264 assertTrue(lock.getQueuedThreads().isEmpty()); 265 lock.lock(); 266 assertTrue(lock.getQueuedThreads().isEmpty()); 267 t1.start(); 268 Thread.sleep(SHORT_DELAY_MS); 269 assertTrue(lock.getQueuedThreads().contains(t1)); 270 t2.start(); 271 Thread.sleep(SHORT_DELAY_MS); 272 assertTrue(lock.getQueuedThreads().contains(t1)); 273 assertTrue(lock.getQueuedThreads().contains(t2)); 274 t1.interrupt(); 275 Thread.sleep(SHORT_DELAY_MS); 276 assertFalse(lock.getQueuedThreads().contains(t1)); 277 assertTrue(lock.getQueuedThreads().contains(t2)); 278 lock.unlock(); 279 Thread.sleep(SHORT_DELAY_MS); 280 assertTrue(lock.getQueuedThreads().isEmpty()); 281 t1.join(); 282 t2.join(); 283 } catch(Exception e){ 284 unexpectedException(); 285 } 286 } 287 288 289 /** 290 * timed tryLock is interruptible. 291 */ 292 public void testInterruptedException2() { 293 final ReentrantLock lock = new ReentrantLock(); 294 lock.lock(); 295 Thread t = new Thread(new Runnable() { 296 public void run() { 297 try { 298 lock.tryLock(MEDIUM_DELAY_MS,TimeUnit.MILLISECONDS); 299 threadShouldThrow(); 300 } catch(InterruptedException success){} 301 } 302 }); 303 try { 304 t.start(); 305 t.interrupt(); 306 } catch(Exception e){ 307 unexpectedException(); 308 } 309 } 310 311 312 /** 313 * TryLock on a locked lock fails 314 */ 315 public void testTryLockWhenLocked() { 316 final ReentrantLock lock = new ReentrantLock(); 317 lock.lock(); 318 Thread t = new Thread(new Runnable() { 319 public void run() { 320 threadAssertFalse(lock.tryLock()); 321 } 322 }); 323 try { 324 t.start(); 325 t.join(); 326 lock.unlock(); 327 } catch(Exception e){ 328 unexpectedException(); 329 } 330 } 331 332 /** 333 * Timed tryLock on a locked lock times out 334 */ 335 public void testTryLock_Timeout() { 336 final ReentrantLock lock = new ReentrantLock(); 337 lock.lock(); 338 Thread t = new Thread(new Runnable() { 339 public void run() { 340 try { 341 threadAssertFalse(lock.tryLock(1, TimeUnit.MILLISECONDS)); 342 } catch (Exception ex) { 343 threadUnexpectedException(); 344 } 345 } 346 }); 347 try { 348 t.start(); 349 t.join(); 350 lock.unlock(); 351 } catch(Exception e){ 352 unexpectedException(); 353 } 354 } 355 356 /** 357 * getHoldCount returns number of recursive holds 358 */ 359 public void testGetHoldCount() { 360 ReentrantLock lock = new ReentrantLock(); 361 for(int i = 1; i <= SIZE; i++) { 362 lock.lock(); 363 assertEquals(i,lock.getHoldCount()); 364 } 365 for(int i = SIZE; i > 0; i--) { 366 lock.unlock(); 367 assertEquals(i-1,lock.getHoldCount()); 368 } 369 } 370 371 372 /** 373 * isLocked is true when locked and false when not 374 */ 375 public void testIsLocked() { 376 final ReentrantLock lock = new ReentrantLock(); 377 lock.lock(); 378 assertTrue(lock.isLocked()); 379 lock.unlock(); 380 assertFalse(lock.isLocked()); 381 Thread t = new Thread(new Runnable() { 382 public void run() { 383 lock.lock(); 384 try { 385 Thread.sleep(SMALL_DELAY_MS); 386 } 387 catch(Exception e) { 388 threadUnexpectedException(); 389 } 390 lock.unlock(); 391 } 392 }); 393 try { 394 t.start(); 395 Thread.sleep(SHORT_DELAY_MS); 396 assertTrue(lock.isLocked()); 397 t.join(); 398 assertFalse(lock.isLocked()); 399 } catch(Exception e){ 400 unexpectedException(); 401 } 402 } 403 404 405 /** 406 * lockInterruptibly is interruptible. 407 */ 408 public void testLockInterruptibly1() { 409 final ReentrantLock lock = new ReentrantLock(); 410 lock.lock(); 411 Thread t = new Thread(new InterruptedLockRunnable(lock)); 412 try { 413 t.start(); 414 Thread.sleep(SHORT_DELAY_MS); 415 t.interrupt(); 416 Thread.sleep(SHORT_DELAY_MS); 417 lock.unlock(); 418 t.join(); 419 } catch(Exception e){ 420 unexpectedException(); 421 } 422 } 423 424 /** 425 * lockInterruptibly succeeds when unlocked, else is interruptible 426 */ 427 public void testLockInterruptibly2() { 428 final ReentrantLock lock = new ReentrantLock(); 429 try { 430 lock.lockInterruptibly(); 431 } catch(Exception e) { 432 unexpectedException(); 433 } 434 Thread t = new Thread(new InterruptedLockRunnable(lock)); 435 try { 436 t.start(); 437 t.interrupt(); 438 assertTrue(lock.isLocked()); 439 assertTrue(lock.isHeldByCurrentThread()); 440 t.join(); 441 } catch(Exception e){ 442 unexpectedException(); 443 } 444 } 445 446 /** 447 * Calling await without holding lock throws IllegalMonitorStateException 448 */ 449 public void testAwait_IllegalMonitor() { 450 final ReentrantLock lock = new ReentrantLock(); 451 final Condition c = lock.newCondition(); 452 try { 453 c.await(); 454 shouldThrow(); 455 } 456 catch (IllegalMonitorStateException success) { 457 } 458 catch (Exception ex) { 459 unexpectedException(); 460 } 461 } 462 463 /** 464 * Calling signal without holding lock throws IllegalMonitorStateException 465 */ 466 public void testSignal_IllegalMonitor() { 467 final ReentrantLock lock = new ReentrantLock(); 468 final Condition c = lock.newCondition(); 469 try { 470 c.signal(); 471 shouldThrow(); 472 } 473 catch (IllegalMonitorStateException success) { 474 } 475 catch (Exception ex) { 476 unexpectedException(); 477 } 478 } 479 480 /** 481 * awaitNanos without a signal times out 482 */ 483 public void testAwaitNanos_Timeout() { 484 final ReentrantLock lock = new ReentrantLock(); 485 final Condition c = lock.newCondition(); 486 try { 487 lock.lock(); 488 long t = c.awaitNanos(100); 489 assertTrue(t <= 0); 490 lock.unlock(); 491 } 492 catch (Exception ex) { 493 unexpectedException(); 494 } 495 } 496 497 /** 498 * timed await without a signal times out 499 */ 500 public void testAwait_Timeout() { 501 final ReentrantLock lock = new ReentrantLock(); 502 final Condition c = lock.newCondition(); 503 try { 504 lock.lock(); 505 c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS); 506 lock.unlock(); 507 } 508 catch (Exception ex) { 509 unexpectedException(); 510 } 511 } 512 513 /** 514 * awaitUntil without a signal times out 515 */ 516 public void testAwaitUntil_Timeout() { 517 final ReentrantLock lock = new ReentrantLock(); 518 final Condition c = lock.newCondition(); 519 try { 520 lock.lock(); 521 java.util.Date d = new java.util.Date(); 522 c.awaitUntil(new java.util.Date(d.getTime() + 10)); 523 lock.unlock(); 524 } 525 catch (Exception ex) { 526 unexpectedException(); 527 } 528 } 529 530 /** 531 * await returns when signalled 532 */ 533 public void testAwait() { 534 final ReentrantLock lock = new ReentrantLock(); 535 final Condition c = lock.newCondition(); 536 Thread t = new Thread(new Runnable() { 537 public void run() { 538 try { 539 lock.lock(); 540 c.await(); 541 lock.unlock(); 542 } 543 catch(InterruptedException e) { 544 threadUnexpectedException(); 545 } 546 } 547 }); 548 549 try { 550 t.start(); 551 Thread.sleep(SHORT_DELAY_MS); 552 lock.lock(); 553 c.signal(); 554 lock.unlock(); 555 t.join(SHORT_DELAY_MS); 556 assertFalse(t.isAlive()); 557 } 558 catch (Exception ex) { 559 unexpectedException(); 560 } 561 } 562 563 /** 564 * hasWaiters throws NPE if null 565 */ 566 public void testHasWaitersNPE() { 567 final ReentrantLock lock = new ReentrantLock(); 568 try { 569 lock.hasWaiters(null); 570 shouldThrow(); 571 } catch (NullPointerException success) { 572 } catch (Exception ex) { 573 unexpectedException(); 574 } 575 } 576 577 /** 578 * getWaitQueueLength throws NPE if null 579 */ 580 public void testGetWaitQueueLengthNPE() { 581 final ReentrantLock lock = new ReentrantLock(); 582 try { 583 lock.getWaitQueueLength(null); 584 shouldThrow(); 585 } catch (NullPointerException success) { 586 } catch (Exception ex) { 587 unexpectedException(); 588 } 589 } 590 591 592 /** 593 * getWaitingThreads throws NPE if null 594 */ 595 public void testGetWaitingThreadsNPE() { 596 final PublicReentrantLock lock = new PublicReentrantLock(); 597 try { 598 lock.getWaitingThreads(null); 599 shouldThrow(); 600 } catch (NullPointerException success) { 601 } catch (Exception ex) { 602 unexpectedException(); 603 } 604 } 605 606 607 /** 608 * hasWaiters throws IAE if not owned 609 */ 610 public void testHasWaitersIAE() { 611 final ReentrantLock lock = new ReentrantLock(); 612 final Condition c = (lock.newCondition()); 613 final ReentrantLock lock2 = new ReentrantLock(); 614 try { 615 lock2.hasWaiters(c); 616 shouldThrow(); 617 } catch (IllegalArgumentException success) { 618 } catch (Exception ex) { 619 unexpectedException(); 620 } 621 } 622 623 /** 624 * hasWaiters throws IMSE if not locked 625 */ 626 public void testHasWaitersIMSE() { 627 final ReentrantLock lock = new ReentrantLock(); 628 final Condition c = (lock.newCondition()); 629 try { 630 lock.hasWaiters(c); 631 shouldThrow(); 632 } catch (IllegalMonitorStateException success) { 633 } catch (Exception ex) { 634 unexpectedException(); 635 } 636 } 637 638 639 /** 640 * getWaitQueueLength throws IAE if not owned 641 */ 642 public void testGetWaitQueueLengthIAE() { 643 final ReentrantLock lock = new ReentrantLock(); 644 final Condition c = (lock.newCondition()); 645 final ReentrantLock lock2 = new ReentrantLock(); 646 try { 647 lock2.getWaitQueueLength(c); 648 shouldThrow(); 649 } catch (IllegalArgumentException success) { 650 } catch (Exception ex) { 651 unexpectedException(); 652 } 653 } 654 655 /** 656 * getWaitQueueLength throws IMSE if not locked 657 */ 658 public void testGetWaitQueueLengthIMSE() { 659 final ReentrantLock lock = new ReentrantLock(); 660 final Condition c = (lock.newCondition()); 661 try { 662 lock.getWaitQueueLength(c); 663 shouldThrow(); 664 } catch (IllegalMonitorStateException success) { 665 } catch (Exception ex) { 666 unexpectedException(); 667 } 668 } 669 670 671 /** 672 * getWaitingThreads throws IAE if not owned 673 */ 674 public void testGetWaitingThreadsIAE() { 675 final PublicReentrantLock lock = new PublicReentrantLock(); 676 final Condition c = (lock.newCondition()); 677 final PublicReentrantLock lock2 = new PublicReentrantLock(); 678 try { 679 lock2.getWaitingThreads(c); 680 shouldThrow(); 681 } catch (IllegalArgumentException success) { 682 } catch (Exception ex) { 683 unexpectedException(); 684 } 685 } 686 687 /** 688 * getWaitingThreads throws IMSE if not locked 689 */ 690 public void testGetWaitingThreadsIMSE() { 691 final PublicReentrantLock lock = new PublicReentrantLock(); 692 final Condition c = (lock.newCondition()); 693 try { 694 lock.getWaitingThreads(c); 695 shouldThrow(); 696 } catch (IllegalMonitorStateException success) { 697 } catch (Exception ex) { 698 unexpectedException(); 699 } 700 } 701 702 703 704 /** 705 * hasWaiters returns true when a thread is waiting, else false 706 */ 707 public void testHasWaiters() { 708 final ReentrantLock lock = new ReentrantLock(); 709 final Condition c = lock.newCondition(); 710 Thread t = new Thread(new Runnable() { 711 public void run() { 712 try { 713 lock.lock(); 714 threadAssertFalse(lock.hasWaiters(c)); 715 threadAssertEquals(0, lock.getWaitQueueLength(c)); 716 c.await(); 717 lock.unlock(); 718 } 719 catch(InterruptedException e) { 720 threadUnexpectedException(); 721 } 722 } 723 }); 724 725 try { 726 t.start(); 727 Thread.sleep(SHORT_DELAY_MS); 728 lock.lock(); 729 assertTrue(lock.hasWaiters(c)); 730 assertEquals(1, lock.getWaitQueueLength(c)); 731 c.signal(); 732 lock.unlock(); 733 Thread.sleep(SHORT_DELAY_MS); 734 lock.lock(); 735 assertFalse(lock.hasWaiters(c)); 736 assertEquals(0, lock.getWaitQueueLength(c)); 737 lock.unlock(); 738 t.join(SHORT_DELAY_MS); 739 assertFalse(t.isAlive()); 740 } 741 catch (Exception ex) { 742 unexpectedException(); 743 } 744 } 745 746 /** 747 * getWaitQueueLength returns number of waiting threads 748 */ 749 public void testGetWaitQueueLength() { 750 final ReentrantLock lock = new ReentrantLock(); 751 final Condition c = lock.newCondition(); 752 Thread t1 = new Thread(new Runnable() { 753 public void run() { 754 try { 755 lock.lock(); 756 threadAssertFalse(lock.hasWaiters(c)); 757 threadAssertEquals(0, lock.getWaitQueueLength(c)); 758 c.await(); 759 lock.unlock(); 760 } 761 catch(InterruptedException e) { 762 threadUnexpectedException(); 763 } 764 } 765 }); 766 767 Thread t2 = new Thread(new Runnable() { 768 public void run() { 769 try { 770 lock.lock(); 771 threadAssertTrue(lock.hasWaiters(c)); 772 threadAssertEquals(1, lock.getWaitQueueLength(c)); 773 c.await(); 774 lock.unlock(); 775 } 776 catch(InterruptedException e) { 777 threadUnexpectedException(); 778 } 779 } 780 }); 781 782 try { 783 t1.start(); 784 Thread.sleep(SHORT_DELAY_MS); 785 t2.start(); 786 Thread.sleep(SHORT_DELAY_MS); 787 lock.lock(); 788 assertTrue(lock.hasWaiters(c)); 789 assertEquals(2, lock.getWaitQueueLength(c)); 790 c.signalAll(); 791 lock.unlock(); 792 Thread.sleep(SHORT_DELAY_MS); 793 lock.lock(); 794 assertFalse(lock.hasWaiters(c)); 795 assertEquals(0, lock.getWaitQueueLength(c)); 796 lock.unlock(); 797 t1.join(SHORT_DELAY_MS); 798 t2.join(SHORT_DELAY_MS); 799 assertFalse(t1.isAlive()); 800 assertFalse(t2.isAlive()); 801 } 802 catch (Exception ex) { 803 unexpectedException(); 804 } 805 } 806 807 /** 808 * getWaitingThreads returns only and all waiting threads 809 */ 810 public void testGetWaitingThreads() { 811 final PublicReentrantLock lock = new PublicReentrantLock(); 812 final Condition c = lock.newCondition(); 813 Thread t1 = new Thread(new Runnable() { 814 public void run() { 815 try { 816 lock.lock(); 817 threadAssertTrue(lock.getWaitingThreads(c).isEmpty()); 818 c.await(); 819 lock.unlock(); 820 } 821 catch(InterruptedException e) { 822 threadUnexpectedException(); 823 } 824 } 825 }); 826 827 Thread t2 = new Thread(new Runnable() { 828 public void run() { 829 try { 830 lock.lock(); 831 threadAssertFalse(lock.getWaitingThreads(c).isEmpty()); 832 c.await(); 833 lock.unlock(); 834 } 835 catch(InterruptedException e) { 836 threadUnexpectedException(); 837 } 838 } 839 }); 840 841 try { 842 lock.lock(); 843 assertTrue(lock.getWaitingThreads(c).isEmpty()); 844 lock.unlock(); 845 t1.start(); 846 Thread.sleep(SHORT_DELAY_MS); 847 t2.start(); 848 Thread.sleep(SHORT_DELAY_MS); 849 lock.lock(); 850 assertTrue(lock.hasWaiters(c)); 851 assertTrue(lock.getWaitingThreads(c).contains(t1)); 852 assertTrue(lock.getWaitingThreads(c).contains(t2)); 853 c.signalAll(); 854 lock.unlock(); 855 Thread.sleep(SHORT_DELAY_MS); 856 lock.lock(); 857 assertFalse(lock.hasWaiters(c)); 858 assertTrue(lock.getWaitingThreads(c).isEmpty()); 859 lock.unlock(); 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 /** A helper class for uninterruptible wait tests */ 871 class UninterruptableThread extends Thread { 872 private ReentrantLock lock; 873 private Condition c; 874 875 public volatile boolean canAwake = false; 876 public volatile boolean interrupted = false; 877 public volatile boolean lockStarted = false; 878 879 public UninterruptableThread(ReentrantLock lock, Condition c) { 880 this.lock = lock; 881 this.c = c; 882 } 883 884 public synchronized void run() { 885 lock.lock(); 886 lockStarted = true; 887 888 while (!canAwake) { 889 c.awaitUninterruptibly(); 890 } 891 892 interrupted = isInterrupted(); 893 lock.unlock(); 894 } 895 } 896 897 /** 898 * awaitUninterruptibly doesn't abort on interrupt 899 */ 900 public void testAwaitUninterruptibly() { 901 final ReentrantLock lock = new ReentrantLock(); 902 final Condition c = lock.newCondition(); 903 UninterruptableThread thread = new UninterruptableThread(lock, c); 904 905 try { 906 thread.start(); 907 908 while (!thread.lockStarted) { 909 Thread.sleep(100); 910 } 911 912 lock.lock(); 913 try { 914 thread.interrupt(); 915 thread.canAwake = true; 916 c.signal(); 917 } finally { 918 lock.unlock(); 919 } 920 921 thread.join(); 922 assertTrue(thread.interrupted); 923 assertFalse(thread.isAlive()); 924 } catch (Exception ex) { 925 unexpectedException(); 926 } 927 } 928 929 /** 930 * await is interruptible 931 */ 932 public void testAwait_Interrupt() { 933 final ReentrantLock lock = new ReentrantLock(); 934 final Condition c = lock.newCondition(); 935 Thread t = new Thread(new Runnable() { 936 public void run() { 937 try { 938 lock.lock(); 939 c.await(); 940 lock.unlock(); 941 threadShouldThrow(); 942 } 943 catch(InterruptedException success) { 944 } 945 } 946 }); 947 948 try { 949 t.start(); 950 Thread.sleep(SHORT_DELAY_MS); 951 t.interrupt(); 952 t.join(SHORT_DELAY_MS); 953 assertFalse(t.isAlive()); 954 } 955 catch (Exception ex) { 956 unexpectedException(); 957 } 958 } 959 960 /** 961 * awaitNanos is interruptible 962 */ 963 public void testAwaitNanos_Interrupt() { 964 final ReentrantLock lock = new ReentrantLock(); 965 final Condition c = lock.newCondition(); 966 Thread t = new Thread(new Runnable() { 967 public void run() { 968 try { 969 lock.lock(); 970 c.awaitNanos(1000 * 1000 * 1000); // 1 sec 971 lock.unlock(); 972 threadShouldThrow(); 973 } 974 catch(InterruptedException success) { 975 } 976 } 977 }); 978 979 try { 980 t.start(); 981 Thread.sleep(SHORT_DELAY_MS); 982 t.interrupt(); 983 t.join(SHORT_DELAY_MS); 984 assertFalse(t.isAlive()); 985 } 986 catch (Exception ex) { 987 unexpectedException(); 988 } 989 } 990 991 /** 992 * awaitUntil is interruptible 993 */ 994 public void testAwaitUntil_Interrupt() { 995 final ReentrantLock lock = new ReentrantLock(); 996 final Condition c = lock.newCondition(); 997 Thread t = new Thread(new Runnable() { 998 public void run() { 999 try { 1000 lock.lock(); 1001 java.util.Date d = new java.util.Date(); 1002 c.awaitUntil(new java.util.Date(d.getTime() + 10000)); 1003 lock.unlock(); 1004 threadShouldThrow(); 1005 } 1006 catch(InterruptedException success) { 1007 } 1008 } 1009 }); 1010 1011 try { 1012 t.start(); 1013 Thread.sleep(SHORT_DELAY_MS); 1014 t.interrupt(); 1015 t.join(SHORT_DELAY_MS); 1016 assertFalse(t.isAlive()); 1017 } 1018 catch (Exception ex) { 1019 unexpectedException(); 1020 } 1021 } 1022 1023 /** 1024 * signalAll wakes up all threads 1025 */ 1026 public void testSignalAll() { 1027 final ReentrantLock lock = new ReentrantLock(); 1028 final Condition c = lock.newCondition(); 1029 Thread t1 = new Thread(new Runnable() { 1030 public void run() { 1031 try { 1032 lock.lock(); 1033 c.await(); 1034 lock.unlock(); 1035 } 1036 catch(InterruptedException e) { 1037 threadUnexpectedException(); 1038 } 1039 } 1040 }); 1041 1042 Thread t2 = new Thread(new Runnable() { 1043 public void run() { 1044 try { 1045 lock.lock(); 1046 c.await(); 1047 lock.unlock(); 1048 } 1049 catch(InterruptedException e) { 1050 threadUnexpectedException(); 1051 } 1052 } 1053 }); 1054 1055 try { 1056 t1.start(); 1057 t2.start(); 1058 Thread.sleep(SHORT_DELAY_MS); 1059 lock.lock(); 1060 c.signalAll(); 1061 lock.unlock(); 1062 t1.join(SHORT_DELAY_MS); 1063 t2.join(SHORT_DELAY_MS); 1064 assertFalse(t1.isAlive()); 1065 assertFalse(t2.isAlive()); 1066 } 1067 catch (Exception ex) { 1068 unexpectedException(); 1069 } 1070 } 1071 1072 /** 1073 * await after multiple reentrant locking preserves lock count 1074 */ 1075 public void testAwaitLockCount() { 1076 final ReentrantLock lock = new ReentrantLock(); 1077 final Condition c = lock.newCondition(); 1078 Thread t1 = new Thread(new Runnable() { 1079 public void run() { 1080 try { 1081 lock.lock(); 1082 threadAssertEquals(1, lock.getHoldCount()); 1083 c.await(); 1084 threadAssertEquals(1, lock.getHoldCount()); 1085 lock.unlock(); 1086 } 1087 catch(InterruptedException e) { 1088 threadUnexpectedException(); 1089 } 1090 } 1091 }); 1092 1093 Thread t2 = new Thread(new Runnable() { 1094 public void run() { 1095 try { 1096 lock.lock(); 1097 lock.lock(); 1098 threadAssertEquals(2, lock.getHoldCount()); 1099 c.await(); 1100 threadAssertEquals(2, lock.getHoldCount()); 1101 lock.unlock(); 1102 lock.unlock(); 1103 } 1104 catch(InterruptedException e) { 1105 threadUnexpectedException(); 1106 } 1107 } 1108 }); 1109 1110 try { 1111 t1.start(); 1112 t2.start(); 1113 Thread.sleep(SHORT_DELAY_MS); 1114 lock.lock(); 1115 c.signalAll(); 1116 lock.unlock(); 1117 t1.join(SHORT_DELAY_MS); 1118 t2.join(SHORT_DELAY_MS); 1119 assertFalse(t1.isAlive()); 1120 assertFalse(t2.isAlive()); 1121 } 1122 catch (Exception ex) { 1123 unexpectedException(); 1124 } 1125 } 1126 1127 /** 1128 * A serialized lock deserializes as unlocked 1129 */ 1130 public void testSerialization() { 1131 ReentrantLock l = new ReentrantLock(); 1132 l.lock(); 1133 l.unlock(); 1134 1135 try { 1136 ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); 1137 ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); 1138 out.writeObject(l); 1139 out.close(); 1140 1141 ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); 1142 ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); 1143 ReentrantLock r = (ReentrantLock) in.readObject(); 1144 r.lock(); 1145 r.unlock(); 1146 } catch(Exception e){ 1147 e.printStackTrace(); 1148 unexpectedException(); 1149 } 1150 } 1151 1152 /** 1153 * toString indicates current lock state 1154 */ 1155 public void testToString() { 1156 ReentrantLock lock = new ReentrantLock(); 1157 String us = lock.toString(); 1158 assertTrue(us.indexOf("Unlocked") >= 0); 1159 lock.lock(); 1160 String ls = lock.toString(); 1161 assertTrue(ls.indexOf("Locked") >= 0); 1162 } 1163 1164} 1165