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