summaryrefslogtreecommitdiff
path: root/jsr166-tests/src/test/java/jsr166/StampedLockTest.java
diff options
context:
space:
mode:
authorPrzemyslaw Szczepaniak <pszczepaniak@google.com>2016-03-11 15:59:10 +0000
committerPrzemyslaw Szczepaniak <pszczepaniak@google.com>2016-03-14 15:40:14 +0000
commit5328e07d282bef36ac8b757bbee16a761415b2c4 (patch)
treed7fd9980442e0d647e1454f54f3d037f4b2280e7 /jsr166-tests/src/test/java/jsr166/StampedLockTest.java
parent8d28fc1d531b4b39def9598de89311aff112f955 (diff)
JSR-166 update
Adapted from sources taken from CVS using: cvs -d ':pserver:anonymous@gee.cs.oswego.edu/home/jsr166/jsr166' checkout -D "03/03/2016 10:00:00 GMT" jsr166 Bug: 27426599 Change-Id: Ic9ba278929f8747d58b69e7d67ec325064588bff
Diffstat (limited to 'jsr166-tests/src/test/java/jsr166/StampedLockTest.java')
-rw-r--r--jsr166-tests/src/test/java/jsr166/StampedLockTest.java884
1 files changed, 884 insertions, 0 deletions
diff --git a/jsr166-tests/src/test/java/jsr166/StampedLockTest.java b/jsr166-tests/src/test/java/jsr166/StampedLockTest.java
new file mode 100644
index 0000000000..d347c7d67e
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/StampedLockTest.java
@@ -0,0 +1,884 @@
+/*
+ * Written by Doug Lea and Martin Buchholz
+ * with assistance from members of JCP JSR-166 Expert Group and
+ * released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+package jsr166;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.StampedLock;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class StampedLockTest extends JSR166TestCase {
+ // android-note: Removed because the CTS runner does a bad job of
+ // retrying tests that have suite() declarations.
+ //
+ // public static void main(String[] args) {
+ // main(suite(), args);
+ // }
+ // public static Test suite() {
+ // return new TestSuite(StampedLockTest.class);
+ // }
+
+ /**
+ * A runnable calling writeLockInterruptibly
+ */
+ class InterruptibleLockRunnable extends CheckedRunnable {
+ final StampedLock lock;
+ InterruptibleLockRunnable(StampedLock l) { lock = l; }
+ public void realRun() throws InterruptedException {
+ lock.writeLockInterruptibly();
+ }
+ }
+
+ /**
+ * A runnable calling writeLockInterruptibly that expects to be
+ * interrupted
+ */
+ class InterruptedLockRunnable extends CheckedInterruptedRunnable {
+ final StampedLock lock;
+ InterruptedLockRunnable(StampedLock l) { lock = l; }
+ public void realRun() throws InterruptedException {
+ lock.writeLockInterruptibly();
+ }
+ }
+
+ /**
+ * Releases write lock, checking isWriteLocked before and after
+ */
+ void releaseWriteLock(StampedLock lock, long s) {
+ assertTrue(lock.isWriteLocked());
+ lock.unlockWrite(s);
+ assertFalse(lock.isWriteLocked());
+ }
+
+ /**
+ * Constructed StampedLock is in unlocked state
+ */
+ public void testConstructor() {
+ StampedLock lock;
+ lock = new StampedLock();
+ assertFalse(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ }
+
+ /**
+ * write-locking and read-locking an unlocked lock succeed
+ */
+ public void testLock() {
+ StampedLock lock = new StampedLock();
+ assertFalse(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ long s = lock.writeLock();
+ assertTrue(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ lock.unlockWrite(s);
+ assertFalse(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ long rs = lock.readLock();
+ assertFalse(lock.isWriteLocked());
+ assertTrue(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 1);
+ lock.unlockRead(rs);
+ assertFalse(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ }
+
+ /**
+ * unlock releases either a read or write lock
+ */
+ public void testUnlock() {
+ StampedLock lock = new StampedLock();
+ assertFalse(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ long s = lock.writeLock();
+ assertTrue(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ lock.unlock(s);
+ assertFalse(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ long rs = lock.readLock();
+ assertFalse(lock.isWriteLocked());
+ assertTrue(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 1);
+ lock.unlock(rs);
+ assertFalse(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ }
+
+ /**
+ * tryUnlockRead/Write succeeds if locked in associated mode else
+ * returns false
+ */
+ public void testTryUnlock() {
+ StampedLock lock = new StampedLock();
+ assertFalse(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ long s = lock.writeLock();
+ assertTrue(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ assertFalse(lock.tryUnlockRead());
+ assertTrue(lock.tryUnlockWrite());
+ assertFalse(lock.tryUnlockWrite());
+ assertFalse(lock.tryUnlockRead());
+ assertFalse(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ long rs = lock.readLock();
+ assertFalse(lock.isWriteLocked());
+ assertTrue(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 1);
+ assertFalse(lock.tryUnlockWrite());
+ assertTrue(lock.tryUnlockRead());
+ assertFalse(lock.tryUnlockRead());
+ assertFalse(lock.tryUnlockWrite());
+ assertFalse(lock.isWriteLocked());
+ assertFalse(lock.isReadLocked());
+ assertEquals(lock.getReadLockCount(), 0);
+ }
+
+ /**
+ * write-unlocking an unlocked lock throws IllegalMonitorStateException
+ */
+ public void testWriteUnlock_IMSE() {
+ StampedLock lock = new StampedLock();
+ try {
+ lock.unlockWrite(0L);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * write-unlocking an unlocked lock throws IllegalMonitorStateException
+ */
+ public void testWriteUnlock_IMSE2() {
+ StampedLock lock = new StampedLock();
+ long s = lock.writeLock();
+ lock.unlockWrite(s);
+ try {
+ lock.unlockWrite(s);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * write-unlocking after readlock throws IllegalMonitorStateException
+ */
+ public void testWriteUnlock_IMSE3() {
+ StampedLock lock = new StampedLock();
+ long s = lock.readLock();
+ try {
+ lock.unlockWrite(s);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * read-unlocking an unlocked lock throws IllegalMonitorStateException
+ */
+ public void testReadUnlock_IMSE() {
+ StampedLock lock = new StampedLock();
+ long s = lock.readLock();
+ lock.unlockRead(s);
+ try {
+ lock.unlockRead(s);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * read-unlocking an unlocked lock throws IllegalMonitorStateException
+ */
+ public void testReadUnlock_IMSE2() {
+ StampedLock lock = new StampedLock();
+ try {
+ lock.unlockRead(0L);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * read-unlocking after writeLock throws IllegalMonitorStateException
+ */
+ public void testReadUnlock_IMSE3() {
+ StampedLock lock = new StampedLock();
+ long s = lock.writeLock();
+ try {
+ lock.unlockRead(s);
+ shouldThrow();
+ } catch (IllegalMonitorStateException success) {}
+ }
+
+ /**
+ * validate(0) fails
+ */
+ public void testValidate0() {
+ StampedLock lock = new StampedLock();
+ assertFalse(lock.validate(0L));
+ }
+
+ /**
+ * A stamp obtained from a successful lock operation validates
+ */
+ public void testValidate() throws InterruptedException {
+ StampedLock lock = new StampedLock();
+ long s = lock.writeLock();
+ assertTrue(lock.validate(s));
+ lock.unlockWrite(s);
+ s = lock.readLock();
+ assertTrue(lock.validate(s));
+ lock.unlockRead(s);
+ assertTrue((s = lock.tryWriteLock()) != 0L);
+ assertTrue(lock.validate(s));
+ lock.unlockWrite(s);
+ assertTrue((s = lock.tryReadLock()) != 0L);
+ assertTrue(lock.validate(s));
+ lock.unlockRead(s);
+ assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
+ assertTrue(lock.validate(s));
+ lock.unlockWrite(s);
+ assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
+ assertTrue(lock.validate(s));
+ lock.unlockRead(s);
+ assertTrue((s = lock.tryOptimisticRead()) != 0L);
+ }
+
+ /**
+ * A stamp obtained from an unsuccessful lock operation does not validate
+ */
+ public void testValidate2() throws InterruptedException {
+ StampedLock lock = new StampedLock();
+ long s;
+ assertTrue((s = lock.writeLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertFalse(lock.validate(lock.tryWriteLock()));
+ assertFalse(lock.validate(lock.tryWriteLock(10L, MILLISECONDS)));
+ assertFalse(lock.validate(lock.tryReadLock()));
+ assertFalse(lock.validate(lock.tryReadLock(10L, MILLISECONDS)));
+ assertFalse(lock.validate(lock.tryOptimisticRead()));
+ lock.unlockWrite(s);
+ }
+
+ /**
+ * writeLockInterruptibly is interruptible
+ */
+ public void testWriteLockInterruptibly_Interruptible()
+ throws InterruptedException {
+ final CountDownLatch running = new CountDownLatch(1);
+ final StampedLock lock = new StampedLock();
+ long s = lock.writeLock();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ running.countDown();
+ lock.writeLockInterruptibly();
+ }});
+
+ running.await();
+ waitForThreadToEnterWaitState(t, 100);
+ t.interrupt();
+ awaitTermination(t);
+ releaseWriteLock(lock, s);
+ }
+
+ /**
+ * timed tryWriteLock is interruptible
+ */
+ public void testWriteTryLock_Interruptible() throws InterruptedException {
+ final CountDownLatch running = new CountDownLatch(1);
+ final StampedLock lock = new StampedLock();
+ long s = lock.writeLock();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ running.countDown();
+ lock.tryWriteLock(2 * LONG_DELAY_MS, MILLISECONDS);
+ }});
+
+ running.await();
+ waitForThreadToEnterWaitState(t, 100);
+ t.interrupt();
+ awaitTermination(t);
+ releaseWriteLock(lock, s);
+ }
+
+ /**
+ * readLockInterruptibly is interruptible
+ */
+ public void testReadLockInterruptibly_Interruptible()
+ throws InterruptedException {
+ final CountDownLatch running = new CountDownLatch(1);
+ final StampedLock lock = new StampedLock();
+ long s = lock.writeLock();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ running.countDown();
+ lock.readLockInterruptibly();
+ }});
+
+ running.await();
+ waitForThreadToEnterWaitState(t, 100);
+ t.interrupt();
+ awaitTermination(t);
+ releaseWriteLock(lock, s);
+ }
+
+ /**
+ * timed tryReadLock is interruptible
+ */
+ public void testReadTryLock_Interruptible() throws InterruptedException {
+ final CountDownLatch running = new CountDownLatch(1);
+ final StampedLock lock = new StampedLock();
+ long s = lock.writeLock();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ running.countDown();
+ lock.tryReadLock(2 * LONG_DELAY_MS, MILLISECONDS);
+ }});
+
+ running.await();
+ waitForThreadToEnterWaitState(t, 100);
+ t.interrupt();
+ awaitTermination(t);
+ releaseWriteLock(lock, s);
+ }
+
+ /**
+ * tryWriteLock on an unlocked lock succeeds
+ */
+ public void testWriteTryLock() {
+ final StampedLock lock = new StampedLock();
+ long s = lock.tryWriteLock();
+ assertTrue(s != 0L);
+ assertTrue(lock.isWriteLocked());
+ long s2 = lock.tryWriteLock();
+ assertEquals(s2, 0L);
+ releaseWriteLock(lock, s);
+ }
+
+ /**
+ * tryWriteLock fails if locked
+ */
+ public void testWriteTryLockWhenLocked() {
+ final StampedLock lock = new StampedLock();
+ long s = lock.writeLock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ long ws = lock.tryWriteLock();
+ assertTrue(ws == 0L);
+ }});
+
+ awaitTermination(t);
+ releaseWriteLock(lock, s);
+ }
+
+ /**
+ * tryReadLock fails if write-locked
+ */
+ public void testReadTryLockWhenLocked() {
+ final StampedLock lock = new StampedLock();
+ long s = lock.writeLock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ long rs = lock.tryReadLock();
+ assertEquals(rs, 0L);
+ }});
+
+ awaitTermination(t);
+ releaseWriteLock(lock, s);
+ }
+
+ /**
+ * Multiple threads can hold a read lock when not write-locked
+ */
+ public void testMultipleReadLocks() {
+ final StampedLock lock = new StampedLock();
+ final long s = lock.readLock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long s2 = lock.tryReadLock();
+ assertTrue(s2 != 0L);
+ lock.unlockRead(s2);
+ long s3 = lock.tryReadLock(LONG_DELAY_MS, MILLISECONDS);
+ assertTrue(s3 != 0L);
+ lock.unlockRead(s3);
+ long s4 = lock.readLock();
+ lock.unlockRead(s4);
+ }});
+
+ awaitTermination(t);
+ lock.unlockRead(s);
+ }
+
+ /**
+ * A writelock succeeds only after a reading thread unlocks
+ */
+ public void testWriteAfterReadLock() throws InterruptedException {
+ final CountDownLatch running = new CountDownLatch(1);
+ final StampedLock lock = new StampedLock();
+ long rs = lock.readLock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ running.countDown();
+ long s = lock.writeLock();
+ lock.unlockWrite(s);
+ }});
+
+ running.await();
+ waitForThreadToEnterWaitState(t, 100);
+ assertFalse(lock.isWriteLocked());
+ lock.unlockRead(rs);
+ awaitTermination(t);
+ assertFalse(lock.isWriteLocked());
+ }
+
+ /**
+ * A writelock succeeds only after reading threads unlock
+ */
+ public void testWriteAfterMultipleReadLocks() {
+ final StampedLock lock = new StampedLock();
+ long s = lock.readLock();
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ long rs = lock.readLock();
+ lock.unlockRead(rs);
+ }});
+
+ awaitTermination(t1);
+
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ long ws = lock.writeLock();
+ lock.unlockWrite(ws);
+ }});
+
+ assertFalse(lock.isWriteLocked());
+ lock.unlockRead(s);
+ awaitTermination(t2);
+ assertFalse(lock.isWriteLocked());
+ }
+
+ /**
+ * Readlocks succeed only after a writing thread unlocks
+ */
+ public void testReadAfterWriteLock() {
+ final StampedLock lock = new StampedLock();
+ final long s = lock.writeLock();
+ Thread t1 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ long rs = lock.readLock();
+ lock.unlockRead(rs);
+ }});
+ Thread t2 = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ long rs = lock.readLock();
+ lock.unlockRead(rs);
+ }});
+
+ releaseWriteLock(lock, s);
+ awaitTermination(t1);
+ awaitTermination(t2);
+ }
+
+ /**
+ * tryReadLock succeeds if readlocked but not writelocked
+ */
+ public void testTryLockWhenReadLocked() {
+ final StampedLock lock = new StampedLock();
+ long s = lock.readLock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ long rs = lock.tryReadLock();
+ threadAssertTrue(rs != 0L);
+ lock.unlockRead(rs);
+ }});
+
+ awaitTermination(t);
+ lock.unlockRead(s);
+ }
+
+ /**
+ * tryWriteLock fails when readlocked
+ */
+ public void testWriteTryLockWhenReadLocked() {
+ final StampedLock lock = new StampedLock();
+ long s = lock.readLock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ long ws = lock.tryWriteLock();
+ threadAssertEquals(ws, 0L);
+ }});
+
+ awaitTermination(t);
+ lock.unlockRead(s);
+ }
+
+ /**
+ * timed tryWriteLock times out if locked
+ */
+ public void testWriteTryLock_Timeout() {
+ final StampedLock lock = new StampedLock();
+ long s = lock.writeLock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ long timeoutMillis = 10;
+ long ws = lock.tryWriteLock(timeoutMillis, MILLISECONDS);
+ assertEquals(ws, 0L);
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ }});
+
+ awaitTermination(t);
+ releaseWriteLock(lock, s);
+ }
+
+ /**
+ * timed tryReadLock times out if write-locked
+ */
+ public void testReadTryLock_Timeout() {
+ final StampedLock lock = new StampedLock();
+ long s = lock.writeLock();
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws InterruptedException {
+ long startTime = System.nanoTime();
+ long timeoutMillis = 10;
+ long rs = lock.tryReadLock(timeoutMillis, MILLISECONDS);
+ assertEquals(rs, 0L);
+ assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+ }});
+
+ awaitTermination(t);
+ assertTrue(lock.isWriteLocked());
+ lock.unlockWrite(s);
+ }
+
+ /**
+ * writeLockInterruptibly succeeds if unlocked, else is interruptible
+ */
+ public void testWriteLockInterruptibly() throws InterruptedException {
+ final CountDownLatch running = new CountDownLatch(1);
+ final StampedLock lock = new StampedLock();
+ long s = lock.writeLockInterruptibly();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ running.countDown();
+ lock.writeLockInterruptibly();
+ }});
+
+ running.await();
+ waitForThreadToEnterWaitState(t, 100);
+ t.interrupt();
+ assertTrue(lock.isWriteLocked());
+ awaitTermination(t);
+ releaseWriteLock(lock, s);
+ }
+
+ /**
+ * readLockInterruptibly succeeds if lock free else is interruptible
+ */
+ public void testReadLockInterruptibly() throws InterruptedException {
+ final CountDownLatch running = new CountDownLatch(1);
+ final StampedLock lock = new StampedLock();
+ long s;
+ s = lock.readLockInterruptibly();
+ lock.unlockRead(s);
+ s = lock.writeLockInterruptibly();
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ running.countDown();
+ lock.readLockInterruptibly();
+ }});
+
+ running.await();
+ waitForThreadToEnterWaitState(t, 100);
+ t.interrupt();
+ awaitTermination(t);
+ releaseWriteLock(lock, s);
+ }
+
+ /**
+ * A serialized lock deserializes as unlocked
+ */
+ public void testSerialization() {
+ StampedLock lock = new StampedLock();
+ lock.writeLock();
+ StampedLock clone = serialClone(lock);
+ assertTrue(lock.isWriteLocked());
+ assertFalse(clone.isWriteLocked());
+ long s = clone.writeLock();
+ assertTrue(clone.isWriteLocked());
+ clone.unlockWrite(s);
+ assertFalse(clone.isWriteLocked());
+ }
+
+ /**
+ * toString indicates current lock state
+ */
+ public void testToString() {
+ StampedLock lock = new StampedLock();
+ assertTrue(lock.toString().contains("Unlocked"));
+ long s = lock.writeLock();
+ assertTrue(lock.toString().contains("Write-locked"));
+ lock.unlockWrite(s);
+ s = lock.readLock();
+ assertTrue(lock.toString().contains("Read-locks"));
+ }
+
+ /**
+ * tryOptimisticRead succeeds and validates if unlocked, fails if locked
+ */
+ public void testValidateOptimistic() throws InterruptedException {
+ StampedLock lock = new StampedLock();
+ long s, p;
+ assertTrue((p = lock.tryOptimisticRead()) != 0L);
+ assertTrue(lock.validate(p));
+ assertTrue((s = lock.writeLock()) != 0L);
+ assertFalse((p = lock.tryOptimisticRead()) != 0L);
+ assertTrue(lock.validate(s));
+ lock.unlockWrite(s);
+ assertTrue((p = lock.tryOptimisticRead()) != 0L);
+ assertTrue(lock.validate(p));
+ assertTrue((s = lock.readLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryOptimisticRead()) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockRead(s);
+ assertTrue((s = lock.tryWriteLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertFalse((p = lock.tryOptimisticRead()) != 0L);
+ lock.unlockWrite(s);
+ assertTrue((s = lock.tryReadLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryOptimisticRead()) != 0L);
+ lock.unlockRead(s);
+ assertTrue(lock.validate(p));
+ assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
+ assertFalse((p = lock.tryOptimisticRead()) != 0L);
+ assertTrue(lock.validate(s));
+ lock.unlockWrite(s);
+ assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryOptimisticRead()) != 0L);
+ lock.unlockRead(s);
+ assertTrue((p = lock.tryOptimisticRead()) != 0L);
+ }
+
+ /**
+ * tryOptimisticRead stamp does not validate if a write lock intervenes
+ */
+ public void testValidateOptimisticWriteLocked() {
+ StampedLock lock = new StampedLock();
+ long s, p;
+ assertTrue((p = lock.tryOptimisticRead()) != 0L);
+ assertTrue((s = lock.writeLock()) != 0L);
+ assertFalse(lock.validate(p));
+ assertFalse((p = lock.tryOptimisticRead()) != 0L);
+ assertTrue(lock.validate(s));
+ lock.unlockWrite(s);
+ }
+
+ /**
+ * tryOptimisticRead stamp does not validate if a write lock
+ * intervenes in another thread
+ */
+ public void testValidateOptimisticWriteLocked2()
+ throws InterruptedException {
+ final CountDownLatch running = new CountDownLatch(1);
+ final StampedLock lock = new StampedLock();
+ long s, p;
+ assertTrue((p = lock.tryOptimisticRead()) != 0L);
+ Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+ public void realRun() throws InterruptedException {
+ lock.writeLockInterruptibly();
+ running.countDown();
+ lock.writeLockInterruptibly();
+ }});
+
+ running.await();
+ assertFalse(lock.validate(p));
+ assertFalse((p = lock.tryOptimisticRead()) != 0L);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * tryConvertToOptimisticRead succeeds and validates if successfully locked,
+ */
+ public void testTryConvertToOptimisticRead() throws InterruptedException {
+ StampedLock lock = new StampedLock();
+ long s, p;
+ s = 0L;
+ assertFalse((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+ assertTrue((s = lock.tryOptimisticRead()) != 0L);
+ assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+ assertTrue((s = lock.writeLock()) != 0L);
+ assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+ assertTrue(lock.validate(p));
+ assertTrue((s = lock.readLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+ assertTrue(lock.validate(p));
+ assertTrue((s = lock.tryWriteLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+ assertTrue(lock.validate(p));
+ assertTrue((s = lock.tryReadLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+ assertTrue(lock.validate(p));
+ assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
+ assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+ assertTrue(lock.validate(p));
+ assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToOptimisticRead(s)) != 0L);
+ assertTrue(lock.validate(p));
+ }
+
+ /**
+ * tryConvertToReadLock succeeds and validates if successfully locked
+ * or lock free;
+ */
+ public void testTryConvertToReadLock() throws InterruptedException {
+ StampedLock lock = new StampedLock();
+ long s, p;
+ s = 0L;
+ assertFalse((p = lock.tryConvertToReadLock(s)) != 0L);
+ assertTrue((s = lock.tryOptimisticRead()) != 0L);
+ assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+ lock.unlockRead(p);
+ assertTrue((s = lock.writeLock()) != 0L);
+ assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockRead(p);
+ assertTrue((s = lock.readLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockRead(p);
+ assertTrue((s = lock.tryWriteLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockRead(p);
+ assertTrue((s = lock.tryReadLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockRead(p);
+ assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
+ assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockRead(p);
+ assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToReadLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockRead(p);
+ }
+
+ /**
+ * tryConvertToWriteLock succeeds and validates if successfully locked
+ * or lock free;
+ */
+ public void testTryConvertToWriteLock() throws InterruptedException {
+ StampedLock lock = new StampedLock();
+ long s, p;
+ s = 0L;
+ assertFalse((p = lock.tryConvertToWriteLock(s)) != 0L);
+ assertTrue((s = lock.tryOptimisticRead()) != 0L);
+ assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+ lock.unlockWrite(p);
+ assertTrue((s = lock.writeLock()) != 0L);
+ assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockWrite(p);
+ assertTrue((s = lock.readLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockWrite(p);
+ assertTrue((s = lock.tryWriteLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockWrite(p);
+ assertTrue((s = lock.tryReadLock()) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockWrite(p);
+ assertTrue((s = lock.tryWriteLock(100L, MILLISECONDS)) != 0L);
+ assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockWrite(p);
+ assertTrue((s = lock.tryReadLock(100L, MILLISECONDS)) != 0L);
+ assertTrue(lock.validate(s));
+ assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+ assertTrue(lock.validate(p));
+ lock.unlockWrite(p);
+ }
+
+ /**
+ * asWriteLock can be locked and unlocked
+ */
+ public void testAsWriteLock() {
+ StampedLock sl = new StampedLock();
+ Lock lock = sl.asWriteLock();
+ lock.lock();
+ assertFalse(lock.tryLock());
+ lock.unlock();
+ assertTrue(lock.tryLock());
+ }
+
+ /**
+ * asReadLock can be locked and unlocked
+ */
+ public void testAsReadLock() {
+ StampedLock sl = new StampedLock();
+ Lock lock = sl.asReadLock();
+ lock.lock();
+ lock.unlock();
+ assertTrue(lock.tryLock());
+ }
+
+ /**
+ * asReadWriteLock.writeLock can be locked and unlocked
+ */
+ public void testAsReadWriteLockWriteLock() {
+ StampedLock sl = new StampedLock();
+ Lock lock = sl.asReadWriteLock().writeLock();
+ lock.lock();
+ assertFalse(lock.tryLock());
+ lock.unlock();
+ assertTrue(lock.tryLock());
+ }
+
+ /**
+ * asReadWriteLock.readLock can be locked and unlocked
+ */
+ public void testAsReadWriteLockReadLock() {
+ StampedLock sl = new StampedLock();
+ Lock lock = sl.asReadWriteLock().readLock();
+ lock.lock();
+ lock.unlock();
+ assertTrue(lock.tryLock());
+ }
+
+}