ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantLockTest.java
Revision: 1.67
Committed: Fri Sep 29 22:31:55 2017 UTC (6 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.66: +63 -0 lines
Log Message:
add testBug8187408

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