--- jsr166/src/test/tck/ReentrantReadWriteLockTest.java 2013/05/30 03:28:55 1.67 +++ jsr166/src/test/tck/ReentrantReadWriteLockTest.java 2017/01/01 20:34:39 1.79 @@ -6,18 +6,24 @@ * Pat Fisher, Mike Judd. */ -import junit.framework.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.concurrent.CountDownLatch; -import static java.util.concurrent.TimeUnit.MILLISECONDS; -import java.util.*; + +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestSuite; public class ReentrantReadWriteLockTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); + main(suite(), args); } public static Test suite() { return new TestSuite(ReentrantReadWriteLockTest.class); @@ -146,28 +152,32 @@ public class ReentrantReadWriteLockTest lock.writeLock().unlock(); } - enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }; + enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil } /** - * Awaits condition using the specified AwaitMethod. + * Awaits condition "indefinitely" using the specified AwaitMethod. */ void await(Condition c, AwaitMethod awaitMethod) throws InterruptedException { + long timeoutMillis = 2 * LONG_DELAY_MS; switch (awaitMethod) { case await: c.await(); break; case awaitTimed: - assertTrue(c.await(2 * LONG_DELAY_MS, MILLISECONDS)); + assertTrue(c.await(timeoutMillis, MILLISECONDS)); break; case awaitNanos: - long nanosRemaining = c.awaitNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS)); - assertTrue(nanosRemaining > 0); + long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis); + long nanosRemaining = c.awaitNanos(timeoutNanos); + assertTrue(nanosRemaining > timeoutNanos / 2); + assertTrue(nanosRemaining <= timeoutNanos); break; case awaitUntil: - java.util.Date d = new java.util.Date(); - assertTrue(c.awaitUntil(new java.util.Date(d.getTime() + 2 * LONG_DELAY_MS))); + assertTrue(c.awaitUntil(delayedDate(timeoutMillis))); break; + default: + throw new AssertionError(); } } @@ -221,14 +231,14 @@ public class ReentrantReadWriteLockTest public void testGetWriteHoldCount() { testGetWriteHoldCount(false); } public void testGetWriteHoldCount_fair() { testGetWriteHoldCount(true); } public void testGetWriteHoldCount(boolean fair) { - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); for (int i = 1; i <= SIZE; i++) { lock.writeLock().lock(); assertEquals(i,lock.getWriteHoldCount()); } for (int i = SIZE; i > 0; i--) { lock.writeLock().unlock(); - assertEquals(i-1,lock.getWriteHoldCount()); + assertEquals(i - 1,lock.getWriteHoldCount()); } } @@ -238,14 +248,14 @@ public class ReentrantReadWriteLockTest public void testGetHoldCount() { testGetHoldCount(false); } public void testGetHoldCount_fair() { testGetHoldCount(true); } public void testGetHoldCount(boolean fair) { - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); for (int i = 1; i <= SIZE; i++) { lock.writeLock().lock(); assertEquals(i,lock.writeLock().getHoldCount()); } for (int i = SIZE; i > 0; i--) { lock.writeLock().unlock(); - assertEquals(i-1,lock.writeLock().getHoldCount()); + assertEquals(i - 1,lock.writeLock().getHoldCount()); } } @@ -255,14 +265,14 @@ public class ReentrantReadWriteLockTest public void testGetReadHoldCount() { testGetReadHoldCount(false); } public void testGetReadHoldCount_fair() { testGetReadHoldCount(true); } public void testGetReadHoldCount(boolean fair) { - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); for (int i = 1; i <= SIZE; i++) { lock.readLock().lock(); assertEquals(i,lock.getReadHoldCount()); } for (int i = SIZE; i > 0; i--) { lock.readLock().unlock(); - assertEquals(i-1,lock.getReadHoldCount()); + assertEquals(i - 1,lock.getReadHoldCount()); } } @@ -272,7 +282,7 @@ public class ReentrantReadWriteLockTest public void testWriteUnlock_IMSE() { testWriteUnlock_IMSE(false); } public void testWriteUnlock_IMSE_fair() { testWriteUnlock_IMSE(true); } public void testWriteUnlock_IMSE(boolean fair) { - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); try { lock.writeLock().unlock(); shouldThrow(); @@ -285,7 +295,7 @@ public class ReentrantReadWriteLockTest public void testReadUnlock_IMSE() { testReadUnlock_IMSE(false); } public void testReadUnlock_IMSE_fair() { testReadUnlock_IMSE(true); } public void testReadUnlock_IMSE(boolean fair) { - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); try { lock.readLock().unlock(); shouldThrow(); @@ -778,11 +788,11 @@ public class ReentrantReadWriteLockTest public void testWriteTryLock_Timeout(boolean fair) { final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(fair); + final long timeoutMillis = timeoutMillis(); lock.writeLock().lock(); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { long startTime = System.nanoTime(); - long timeoutMillis = 10; assertFalse(lock.writeLock().tryLock(timeoutMillis, MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis); }}); @@ -802,7 +812,7 @@ public class ReentrantReadWriteLockTest Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { long startTime = System.nanoTime(); - long timeoutMillis = 10; + long timeoutMillis = timeoutMillis(); assertFalse(lock.readLock().tryLock(timeoutMillis, MILLISECONDS)); assertTrue(millisElapsedSince(startTime) >= timeoutMillis); }}); @@ -822,9 +832,7 @@ public class ReentrantReadWriteLockTest new PublicReentrantReadWriteLock(fair); try { lock.writeLock().lockInterruptibly(); - } catch (InterruptedException ie) { - threadUnexpectedException(ie); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } Thread t = newStartedThread(new CheckedInterruptedRunnable() { public void realRun() throws InterruptedException { lock.writeLock().lockInterruptibly(); @@ -849,9 +857,7 @@ public class ReentrantReadWriteLockTest lock.readLock().lockInterruptibly(); lock.readLock().unlock(); lock.writeLock().lockInterruptibly(); - } catch (InterruptedException ie) { - threadUnexpectedException(ie); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } Thread t = newStartedThread(new CheckedInterruptedRunnable() { public void realRun() throws InterruptedException { lock.readLock().lockInterruptibly(); @@ -877,7 +883,9 @@ public class ReentrantReadWriteLockTest await(c, awaitMethod); shouldThrow(); } catch (IllegalMonitorStateException success) { - } catch (InterruptedException e) { threadUnexpectedException(e); } + } catch (InterruptedException fail) { + threadUnexpectedException(fail); + } assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); } } @@ -916,21 +924,18 @@ public class ReentrantReadWriteLockTest public void testAwaitNanos_Timeout() { testAwaitNanos_Timeout(false); } public void testAwaitNanos_Timeout_fair() { testAwaitNanos_Timeout(true); } public void testAwaitNanos_Timeout(boolean fair) { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final Condition c = lock.writeLock().newCondition(); + final long timeoutMillis = timeoutMillis(); + lock.writeLock().lock(); + final long startTime = System.nanoTime(); + final long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis); try { - final ReentrantReadWriteLock lock = - new ReentrantReadWriteLock(fair); - final Condition c = lock.writeLock().newCondition(); - lock.writeLock().lock(); - long startTime = System.nanoTime(); - long timeoutMillis = 10; - long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis); long nanosRemaining = c.awaitNanos(timeoutNanos); assertTrue(nanosRemaining <= 0); - assertTrue(millisElapsedSince(startTime) >= timeoutMillis); - lock.writeLock().unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } + assertTrue(millisElapsedSince(startTime) >= timeoutMillis); + lock.writeLock().unlock(); } /** @@ -939,19 +944,16 @@ public class ReentrantReadWriteLockTest public void testAwait_Timeout() { testAwait_Timeout(false); } public void testAwait_Timeout_fair() { testAwait_Timeout(true); } public void testAwait_Timeout(boolean fair) { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final Condition c = lock.writeLock().newCondition(); + final long timeoutMillis = timeoutMillis(); + lock.writeLock().lock(); + final long startTime = System.nanoTime(); try { - final ReentrantReadWriteLock lock = - new ReentrantReadWriteLock(fair); - final Condition c = lock.writeLock().newCondition(); - lock.writeLock().lock(); - long startTime = System.nanoTime(); - long timeoutMillis = 10; assertFalse(c.await(timeoutMillis, MILLISECONDS)); - assertTrue(millisElapsedSince(startTime) >= timeoutMillis); - lock.writeLock().unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + } catch (InterruptedException fail) { threadUnexpectedException(fail); } + assertTrue(millisElapsedSince(startTime) >= timeoutMillis); + lock.writeLock().unlock(); } /** @@ -960,20 +962,17 @@ public class ReentrantReadWriteLockTest public void testAwaitUntil_Timeout() { testAwaitUntil_Timeout(false); } public void testAwaitUntil_Timeout_fair() { testAwaitUntil_Timeout(true); } public void testAwaitUntil_Timeout(boolean fair) { + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final Condition c = lock.writeLock().newCondition(); + lock.writeLock().lock(); + // We shouldn't assume that nanoTime and currentTimeMillis + // use the same time source, so don't use nanoTime here. + final java.util.Date delayedDate = delayedDate(timeoutMillis()); try { - final ReentrantReadWriteLock lock = - new ReentrantReadWriteLock(fair); - final Condition c = lock.writeLock().newCondition(); - lock.writeLock().lock(); - long startTime = System.nanoTime(); - long timeoutMillis = 10; - java.util.Date d = new java.util.Date(); - assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + timeoutMillis))); - assertTrue(millisElapsedSince(startTime) >= timeoutMillis); - lock.writeLock().unlock(); - } catch (InterruptedException e) { - threadUnexpectedException(e); - } + assertFalse(c.awaitUntil(delayedDate)); + } catch (InterruptedException fail) { threadUnexpectedException(fail); } + assertTrue(new java.util.Date().getTime() >= delayedDate.getTime()); + lock.writeLock().unlock(); } /** @@ -1229,7 +1228,7 @@ public class ReentrantReadWriteLockTest public void testSerialization() { testSerialization(false); } public void testSerialization_fair() { testSerialization(true); } public void testSerialization(boolean fair) { - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); lock.writeLock().lock(); lock.readLock().lock(); @@ -1631,14 +1630,20 @@ public class ReentrantReadWriteLockTest public void testToString() { testToString(false); } public void testToString_fair() { testToString(true); } public void testToString(boolean fair) { - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); assertTrue(lock.toString().contains("Write locks = 0")); assertTrue(lock.toString().contains("Read locks = 0")); lock.writeLock().lock(); assertTrue(lock.toString().contains("Write locks = 1")); assertTrue(lock.toString().contains("Read locks = 0")); + lock.writeLock().lock(); + assertTrue(lock.toString().contains("Write locks = 2")); + assertTrue(lock.toString().contains("Read locks = 0")); + lock.writeLock().unlock(); lock.writeLock().unlock(); lock.readLock().lock(); + assertTrue(lock.toString().contains("Write locks = 0")); + assertTrue(lock.toString().contains("Read locks = 1")); lock.readLock().lock(); assertTrue(lock.toString().contains("Write locks = 0")); assertTrue(lock.toString().contains("Read locks = 2")); @@ -1650,11 +1655,16 @@ public class ReentrantReadWriteLockTest public void testReadLockToString() { testReadLockToString(false); } public void testReadLockToString_fair() { testReadLockToString(true); } public void testReadLockToString(boolean fair) { - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); assertTrue(lock.readLock().toString().contains("Read locks = 0")); lock.readLock().lock(); + assertTrue(lock.readLock().toString().contains("Read locks = 1")); lock.readLock().lock(); assertTrue(lock.readLock().toString().contains("Read locks = 2")); + lock.readLock().unlock(); + assertTrue(lock.readLock().toString().contains("Read locks = 1")); + lock.readLock().unlock(); + assertTrue(lock.readLock().toString().contains("Read locks = 0")); } /** @@ -1663,10 +1673,10 @@ public class ReentrantReadWriteLockTest public void testWriteLockToString() { testWriteLockToString(false); } public void testWriteLockToString_fair() { testWriteLockToString(true); } public void testWriteLockToString(boolean fair) { - ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); + final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair); assertTrue(lock.writeLock().toString().contains("Unlocked")); lock.writeLock().lock(); - assertTrue(lock.writeLock().toString().contains("Locked")); + assertTrue(lock.writeLock().toString().contains("Locked by")); lock.writeLock().unlock(); assertTrue(lock.writeLock().toString().contains("Unlocked")); }