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