ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ReentrantLockTest.java
Revision: 1.68
Committed: Tue Jan 23 20:44:11 2018 UTC (6 years, 3 months ago) by jsr166
Branch: MAIN
Changes since 1.67: +1 -2 lines
Log Message:
migrate from AssertionFailedError to AssertionError

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