--- jsr166/src/test/tck/ReentrantLockTest.java 2009/11/30 08:31:09 1.32 +++ jsr166/src/test/tck/ReentrantLockTest.java 2011/05/07 03:36:23 1.43 @@ -1,7 +1,7 @@ /* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain + * http://creativecommons.org/publicdomain/zero/1.0/ * Other contributors include Andrew Wright, Jeffrey Hayes, * Pat Fisher, Mike Judd. */ @@ -15,7 +15,7 @@ import java.io.*; public class ReentrantLockTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run (suite()); + junit.textui.TestRunner.run(suite()); } public static Test suite() { return new TestSuite(ReentrantLockTest.class); @@ -56,8 +56,28 @@ public class ReentrantLockTest extends J public Collection getWaitingThreads(Condition c) { return super.getWaitingThreads(c); } + } + /** + * Checks that condition c has no waiters. + */ + void assertHasNoWaiters(PublicReentrantLock lock, Condition c) { + assertHasWaiters(lock, c, new Thread[] {}); + } + /** + * Checks that condition c has exactly the given waiter threads. + */ + void assertHasWaiters(PublicReentrantLock lock, Condition c, + Thread... threads) { + lock.lock(); + assertEquals(threads.length > 0, lock.hasWaiters(c)); + assertEquals(threads.length, lock.getWaitQueueLength(c)); + assertEquals(threads.length == 0, lock.getWaitingThreads(c).isEmpty()); + assertEquals(threads.length, lock.getWaitingThreads(c).size()); + assertEquals(new HashSet(lock.getWaitingThreads(c)), + new HashSet(Arrays.asList(threads))); + lock.unlock(); } /** @@ -122,19 +142,19 @@ public class ReentrantLockTest extends J assertFalse(lock.hasQueuedThreads()); lock.lock(); t1.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertTrue(lock.hasQueuedThreads()); t2.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertTrue(lock.hasQueuedThreads()); t1.interrupt(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertTrue(lock.hasQueuedThreads()); lock.unlock(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertFalse(lock.hasQueuedThreads()); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -147,19 +167,19 @@ public class ReentrantLockTest extends J assertEquals(0, lock.getQueueLength()); lock.lock(); t1.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertEquals(1, lock.getQueueLength()); t2.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertEquals(2, lock.getQueueLength()); t1.interrupt(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertEquals(1, lock.getQueueLength()); lock.unlock(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertEquals(0, lock.getQueueLength()); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -172,19 +192,19 @@ public class ReentrantLockTest extends J assertEquals(0, lock.getQueueLength()); lock.lock(); t1.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertEquals(1, lock.getQueueLength()); t2.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertEquals(2, lock.getQueueLength()); t1.interrupt(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertEquals(1, lock.getQueueLength()); lock.unlock(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertEquals(0, lock.getQueueLength()); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -209,23 +229,23 @@ public class ReentrantLockTest extends J assertFalse(sync.hasQueuedThread(t2)); sync.lock(); t1.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertTrue(sync.hasQueuedThread(t1)); t2.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertTrue(sync.hasQueuedThread(t1)); assertTrue(sync.hasQueuedThread(t2)); t1.interrupt(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertFalse(sync.hasQueuedThread(t1)); assertTrue(sync.hasQueuedThread(t2)); sync.unlock(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertFalse(sync.hasQueuedThread(t1)); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertFalse(sync.hasQueuedThread(t2)); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); } @@ -240,21 +260,21 @@ public class ReentrantLockTest extends J lock.lock(); assertTrue(lock.getQueuedThreads().isEmpty()); t1.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertTrue(lock.getQueuedThreads().contains(t1)); t2.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertTrue(lock.getQueuedThreads().contains(t1)); assertTrue(lock.getQueuedThreads().contains(t2)); t1.interrupt(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertFalse(lock.getQueuedThreads().contains(t1)); assertTrue(lock.getQueuedThreads().contains(t2)); lock.unlock(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertTrue(lock.getQueuedThreads().isEmpty()); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); } @@ -264,15 +284,14 @@ public class ReentrantLockTest extends J public void testInterruptedException2() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); lock.lock(); - Thread t = new Thread(new CheckedInterruptedRunnable() { + Thread t = newStartedThread(new CheckedInterruptedRunnable() { public void realRun() throws InterruptedException { lock.tryLock(MEDIUM_DELAY_MS,MILLISECONDS); }}); - t.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); t.interrupt(); - t.join(); + awaitTermination(t); } @@ -282,13 +301,12 @@ public class ReentrantLockTest extends J public void testTryLockWhenLocked() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); lock.lock(); - Thread t = new Thread(new CheckedRunnable() { + Thread t = newStartedThread(new CheckedRunnable() { public void realRun() { - threadAssertFalse(lock.tryLock()); + assertFalse(lock.tryLock()); }}); - t.start(); - t.join(); + awaitTermination(t); lock.unlock(); } @@ -298,13 +316,12 @@ public class ReentrantLockTest extends J public void testTryLock_Timeout() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); lock.lock(); - Thread t = new Thread(new CheckedRunnable() { + Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - threadAssertFalse(lock.tryLock(1, MILLISECONDS)); + assertFalse(lock.tryLock(1, MILLISECONDS)); }}); - t.start(); - t.join(); + awaitTermination(t); lock.unlock(); } @@ -333,17 +350,16 @@ public class ReentrantLockTest extends J assertTrue(lock.isLocked()); lock.unlock(); assertFalse(lock.isLocked()); - Thread t = new Thread(new CheckedRunnable() { + Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); - Thread.sleep(SMALL_DELAY_MS); + delay(SMALL_DELAY_MS); lock.unlock(); }}); - t.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); assertTrue(lock.isLocked()); - t.join(); + awaitTermination(t); assertFalse(lock.isLocked()); } @@ -354,13 +370,12 @@ public class ReentrantLockTest extends J public void testLockInterruptibly1() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); lock.lock(); - Thread t = new Thread(new InterruptedLockRunnable(lock)); - t.start(); - Thread.sleep(SHORT_DELAY_MS); + Thread t = newStartedThread(new InterruptedLockRunnable(lock)); + delay(SHORT_DELAY_MS); t.interrupt(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); lock.unlock(); - t.join(); + awaitTermination(t); } /** @@ -369,13 +384,12 @@ public class ReentrantLockTest extends J public void testLockInterruptibly2() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); lock.lockInterruptibly(); - Thread t = new Thread(new InterruptedLockRunnable(lock)); - t.start(); - Thread.sleep(SHORT_DELAY_MS); + Thread t = newStartedThread(new InterruptedLockRunnable(lock)); + delay(SHORT_DELAY_MS); t.interrupt(); assertTrue(lock.isLocked()); assertTrue(lock.isHeldByCurrentThread()); - t.join(); + awaitTermination(t); } /** @@ -415,7 +429,7 @@ public class ReentrantLockTest extends J } /** - * timed await without a signal times out + * timed await without a signal times out */ public void testAwait_Timeout() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); @@ -443,20 +457,18 @@ public class ReentrantLockTest extends J public void testAwait() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); final Condition c = lock.newCondition(); - Thread t = new Thread(new CheckedRunnable() { + Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); c.await(); lock.unlock(); }}); - t.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); lock.lock(); c.signal(); lock.unlock(); - t.join(SHORT_DELAY_MS); - assertFalse(t.isAlive()); + awaitTermination(t); } /** @@ -578,29 +590,27 @@ public class ReentrantLockTest extends J public void testHasWaiters() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); final Condition c = lock.newCondition(); - Thread t = new Thread(new CheckedRunnable() { + Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); - threadAssertFalse(lock.hasWaiters(c)); - threadAssertEquals(0, lock.getWaitQueueLength(c)); + assertFalse(lock.hasWaiters(c)); + assertEquals(0, lock.getWaitQueueLength(c)); c.await(); lock.unlock(); }}); - t.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); lock.lock(); assertTrue(lock.hasWaiters(c)); assertEquals(1, lock.getWaitQueueLength(c)); c.signal(); lock.unlock(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); lock.lock(); assertFalse(lock.hasWaiters(c)); assertEquals(0, lock.getWaitQueueLength(c)); lock.unlock(); - t.join(SHORT_DELAY_MS); - assertFalse(t.isAlive()); + awaitTermination(t); } /** @@ -609,42 +619,39 @@ public class ReentrantLockTest extends J public void testGetWaitQueueLength() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); final Condition c = lock.newCondition(); - Thread t1 = new Thread(new CheckedRunnable() { + Thread t1 = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); - threadAssertFalse(lock.hasWaiters(c)); - threadAssertEquals(0, lock.getWaitQueueLength(c)); + assertFalse(lock.hasWaiters(c)); + assertEquals(0, lock.getWaitQueueLength(c)); c.await(); lock.unlock(); }}); - Thread t2 = new Thread(new CheckedRunnable() { + delay(SHORT_DELAY_MS); + + Thread t2 = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); - threadAssertTrue(lock.hasWaiters(c)); - threadAssertEquals(1, lock.getWaitQueueLength(c)); + assertTrue(lock.hasWaiters(c)); + assertEquals(1, lock.getWaitQueueLength(c)); c.await(); lock.unlock(); }}); - t1.start(); - Thread.sleep(SHORT_DELAY_MS); - t2.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); lock.lock(); assertTrue(lock.hasWaiters(c)); assertEquals(2, lock.getWaitQueueLength(c)); c.signalAll(); lock.unlock(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); lock.lock(); assertFalse(lock.hasWaiters(c)); assertEquals(0, lock.getWaitQueueLength(c)); lock.unlock(); - t1.join(SHORT_DELAY_MS); - t2.join(SHORT_DELAY_MS); - assertFalse(t1.isAlive()); - assertFalse(t2.isAlive()); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -656,7 +663,7 @@ public class ReentrantLockTest extends J Thread t1 = new Thread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); - threadAssertTrue(lock.getWaitingThreads(c).isEmpty()); + assertTrue(lock.getWaitingThreads(c).isEmpty()); c.await(); lock.unlock(); }}); @@ -664,7 +671,7 @@ public class ReentrantLockTest extends J Thread t2 = new Thread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); - threadAssertFalse(lock.getWaitingThreads(c).isEmpty()); + assertFalse(lock.getWaitingThreads(c).isEmpty()); c.await(); lock.unlock(); }}); @@ -673,24 +680,22 @@ public class ReentrantLockTest extends J assertTrue(lock.getWaitingThreads(c).isEmpty()); lock.unlock(); t1.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); t2.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); lock.lock(); assertTrue(lock.hasWaiters(c)); assertTrue(lock.getWaitingThreads(c).contains(t1)); assertTrue(lock.getWaitingThreads(c).contains(t2)); c.signalAll(); lock.unlock(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); lock.lock(); assertFalse(lock.hasWaiters(c)); assertTrue(lock.getWaitingThreads(c).isEmpty()); lock.unlock(); - t1.join(SHORT_DELAY_MS); - t2.join(SHORT_DELAY_MS); - assertFalse(t1.isAlive()); - assertFalse(t2.isAlive()); + awaitTermination(t1); + awaitTermination(t2); } /** A helper class for uninterruptible wait tests */ @@ -731,7 +736,7 @@ public class ReentrantLockTest extends J thread.start(); while (!thread.lockStarted) { - Thread.sleep(100); + delay(100); } lock.lock(); @@ -752,19 +757,32 @@ public class ReentrantLockTest extends J * await is interruptible */ public void testAwait_Interrupt() throws InterruptedException { - final ReentrantLock lock = new ReentrantLock(); + final PublicReentrantLock lock = new PublicReentrantLock(); final Condition c = lock.newCondition(); - Thread t = new Thread(new CheckedInterruptedRunnable() { + final CountDownLatch locked = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedInterruptedRunnable() { public void realRun() throws InterruptedException { lock.lock(); - c.await(); + assertTrue(lock.isLocked()); + assertTrue(lock.isHeldByCurrentThread()); + assertHasNoWaiters(lock, c); + locked.countDown(); + try { + c.await(); + } finally { + assertTrue(lock.isLocked()); + assertTrue(lock.isHeldByCurrentThread()); + assertHasNoWaiters(lock, c); + lock.unlock(); + assertFalse(Thread.interrupted()); + } }}); - t.start(); - Thread.sleep(SHORT_DELAY_MS); + locked.await(); + assertHasWaiters(lock, c, t); t.interrupt(); - t.join(SHORT_DELAY_MS); - assertFalse(t.isAlive()); + awaitTermination(t); + assertFalse(lock.isLocked()); } /** @@ -773,17 +791,15 @@ public class ReentrantLockTest extends J public void testAwaitNanos_Interrupt() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); final Condition c = lock.newCondition(); - Thread t = new Thread(new CheckedInterruptedRunnable() { + Thread t = newStartedThread(new CheckedInterruptedRunnable() { public void realRun() throws InterruptedException { lock.lock(); - c.awaitNanos(LONG_DELAY_MS * 1000L * 1000L); + c.awaitNanos(MILLISECONDS.toNanos(LONG_DELAY_MS)); }}); - t.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); t.interrupt(); - t.join(SHORT_DELAY_MS); - assertFalse(t.isAlive()); + awaitTermination(t); } /** @@ -792,18 +808,16 @@ public class ReentrantLockTest extends J public void testAwaitUntil_Interrupt() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); final Condition c = lock.newCondition(); - Thread t = new Thread(new CheckedInterruptedRunnable() { + Thread t = newStartedThread(new CheckedInterruptedRunnable() { public void realRun() throws InterruptedException { lock.lock(); java.util.Date d = new java.util.Date(); c.awaitUntil(new java.util.Date(d.getTime() + 10000)); }}); - t.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); t.interrupt(); - t.join(SHORT_DELAY_MS); - assertFalse(t.isAlive()); + awaitTermination(t); } /** @@ -812,30 +826,26 @@ public class ReentrantLockTest extends J public void testSignalAll() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); final Condition c = lock.newCondition(); - Thread t1 = new Thread(new CheckedRunnable() { + Thread t1 = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); c.await(); lock.unlock(); }}); - Thread t2 = new Thread(new CheckedRunnable() { + Thread t2 = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); c.await(); lock.unlock(); }}); - t1.start(); - t2.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); lock.lock(); c.signalAll(); lock.unlock(); - t1.join(SHORT_DELAY_MS); - t2.join(SHORT_DELAY_MS); - assertFalse(t1.isAlive()); - assertFalse(t2.isAlive()); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -844,36 +854,32 @@ public class ReentrantLockTest extends J public void testAwaitLockCount() throws InterruptedException { final ReentrantLock lock = new ReentrantLock(); final Condition c = lock.newCondition(); - Thread t1 = new Thread(new CheckedRunnable() { + Thread t1 = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); - threadAssertEquals(1, lock.getHoldCount()); + assertEquals(1, lock.getHoldCount()); c.await(); - threadAssertEquals(1, lock.getHoldCount()); + assertEquals(1, lock.getHoldCount()); lock.unlock(); }}); - Thread t2 = new Thread(new CheckedRunnable() { + Thread t2 = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { lock.lock(); lock.lock(); - threadAssertEquals(2, lock.getHoldCount()); + assertEquals(2, lock.getHoldCount()); c.await(); - threadAssertEquals(2, lock.getHoldCount()); + assertEquals(2, lock.getHoldCount()); lock.unlock(); lock.unlock(); }}); - t1.start(); - t2.start(); - Thread.sleep(SHORT_DELAY_MS); + delay(SHORT_DELAY_MS); lock.lock(); c.signalAll(); lock.unlock(); - t1.join(SHORT_DELAY_MS); - t2.join(SHORT_DELAY_MS); - assertFalse(t1.isAlive()); - assertFalse(t2.isAlive()); + awaitTermination(t1); + awaitTermination(t2); } /** @@ -889,7 +895,7 @@ public class ReentrantLockTest extends J new ObjectOutputStream(new BufferedOutputStream(bout)); out.writeObject(l); out.close(); - + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); ObjectInputStream in =