ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantLockTest.java
Revision: 1.71
Committed: Thu Sep 26 20:48:52 2019 UTC (4 years, 6 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.70: +8 -8 lines
Log Message:
whitespace

File Contents

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