--- jsr166/src/test/tck/StampedLockTest.java 2017/02/18 14:32:09 1.33 +++ jsr166/src/test/tck/StampedLockTest.java 2017/09/21 17:52:52 1.38 @@ -7,7 +7,6 @@ import static java.util.concurrent.TimeUnit.DAYS; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static java.util.concurrent.TimeUnit.SECONDS; import java.util.ArrayList; import java.util.List; @@ -248,9 +247,11 @@ public class StampedLockTest extends JSR long s = assertNonZero(lock.writeLock()); assertTrue(lock.validate(s)); assertFalse(lock.validate(lock.tryWriteLock())); - assertFalse(lock.validate(lock.tryWriteLock(0L, SECONDS))); + assertFalse(lock.validate(lock.tryWriteLock(randomExpiredTimeout(), + randomTimeUnit()))); assertFalse(lock.validate(lock.tryReadLock())); - assertFalse(lock.validate(lock.tryReadLock(0L, SECONDS))); + assertFalse(lock.validate(lock.tryWriteLock(randomExpiredTimeout(), + randomTimeUnit()))); assertFalse(lock.validate(lock.tryOptimisticRead())); lock.unlockWrite(s); } @@ -491,8 +492,8 @@ public class StampedLockTest extends JSR lock.unlockWrite(s); }}); - aboutToLock.await(); - waitForThreadToEnterWaitState(t); + await(aboutToLock); + assertThreadBlocks(t, Thread.State.WAITING); assertFalse(lock.isWriteLocked()); assertTrue(lock.isReadLocked()); lock.unlockRead(rs); @@ -546,8 +547,8 @@ public class StampedLockTest extends JSR Thread t2 = newStartedThread(acquireReleaseReadLock); await(threadsStarted); - waitForThreadToEnterWaitState(t1); - waitForThreadToEnterWaitState(t2); + assertThreadBlocks(t1, Thread.State.WAITING); + assertThreadBlocks(t2, Thread.State.WAITING); assertTrue(lock.isWriteLocked()); assertFalse(lock.isReadLocked()); releaseWriteLock(lock, s); @@ -750,10 +751,10 @@ public class StampedLockTest extends JSR lock.writeLockInterruptibly(); }}); - locked.await(); + await(locked); assertFalse(lock.validate(p)); assertEquals(0L, lock.tryOptimisticRead()); - waitForThreadToEnterWaitState(t); + assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); awaitTermination(t); assertTrue(lock.isWriteLocked()); @@ -1179,4 +1180,50 @@ public class StampedLockTest extends JSR } assertUnlocked(lock); } + + /** + * Stamped locks are not reentrant. + */ + public void testNonReentrant() throws InterruptedException { + final StampedLock lock = new StampedLock(); + long stamp; + + stamp = lock.writeLock(); + assertValid(lock, stamp); + assertEquals(0L, lock.tryWriteLock(0L, DAYS)); + assertEquals(0L, lock.tryReadLock(0L, DAYS)); + assertValid(lock, stamp); + lock.unlockWrite(stamp); + + stamp = lock.tryWriteLock(1L, DAYS); + assertEquals(0L, lock.tryWriteLock(0L, DAYS)); + assertValid(lock, stamp); + lock.unlockWrite(stamp); + + stamp = lock.readLock(); + assertEquals(0L, lock.tryWriteLock(0L, DAYS)); + assertValid(lock, stamp); + lock.unlockRead(stamp); + } + + /** + * """StampedLocks have no notion of ownership. Locks acquired in + * one thread can be released or converted in another.""" + */ + public void testNoOwnership() throws Throwable { + ArrayList> futures = new ArrayList<>(); + for (Function writeLocker : writeLockers()) + for (BiConsumer writeUnlocker : writeUnlockers()) { + StampedLock lock = new StampedLock(); + long stamp = writeLocker.apply(lock); + futures.add(cachedThreadPool.submit(new CheckedRunnable() { + public void realRun() { + writeUnlocker.accept(lock, stamp); + assertUnlocked(lock); + assertFalse(lock.validate(stamp)); + }})); + } + for (Future future : futures) + assertNull(future.get()); + } }