--- jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java 2015/04/25 04:55:30 1.34 +++ jsr166/src/test/tck/AbstractQueuedLongSynchronizerTest.java 2017/09/29 19:34:37 1.42 @@ -19,6 +19,7 @@ import junit.framework.AssertionFailedEr import junit.framework.Test; import junit.framework.TestSuite; +@SuppressWarnings("WaitNotInLoop") // we implement spurious-wakeup freedom public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase { public static void main(String[] args) { main(suite(), args); @@ -30,6 +31,9 @@ public class AbstractQueuedLongSynchroni /** * A simple mutex class, adapted from the class javadoc. Exclusive * acquire tests exercise this as a sample user extension. + * + * Unlike the javadoc sample, we don't track owner thread via + * AbstractOwnableSynchronizer methods. */ static class Mutex extends AbstractQueuedLongSynchronizer { /** An eccentric value > 32 bits for locked synchronizer state. */ @@ -37,18 +41,19 @@ public class AbstractQueuedLongSynchroni static final long UNLOCKED = 0; - public boolean isHeldExclusively() { + /** Owner thread is untracked, so this is really just isLocked(). */ + @Override public boolean isHeldExclusively() { long state = getState(); assertTrue(state == UNLOCKED || state == LOCKED); return state == LOCKED; } - public boolean tryAcquire(long acquires) { + @Override protected boolean tryAcquire(long acquires) { assertEquals(LOCKED, acquires); return compareAndSetState(UNLOCKED, LOCKED); } - public boolean tryRelease(long releases) { + @Override protected boolean tryRelease(long releases) { if (getState() != LOCKED) throw new IllegalMonitorStateException(); setState(UNLOCKED); return true; @@ -78,13 +83,14 @@ public class AbstractQueuedLongSynchroni release(LOCKED); } + /** Faux-Implements Lock.newCondition(). */ public ConditionObject newCondition() { return new ConditionObject(); } } /** - * A simple latch class, to test shared mode. + * A minimal latch class, to test shared mode. */ static class BooleanLatch extends AbstractQueuedLongSynchronizer { public boolean isSignalled() { return getState() != 0; } @@ -235,26 +241,34 @@ public class AbstractQueuedLongSynchroni * default timeout duration). */ void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) { - long timeoutMillis = timeoutMillis(); - long startTime = System.nanoTime(); + final long timeoutMillis = timeoutMillis(); + final long startTime; try { switch (awaitMethod) { case awaitTimed: + startTime = System.nanoTime(); assertFalse(c.await(timeoutMillis, MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis); break; case awaitNanos: + startTime = System.nanoTime(); long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis); long nanosRemaining = c.awaitNanos(nanosTimeout); assertTrue(nanosRemaining <= 0); + assertTrue(nanosRemaining > -MILLISECONDS.toNanos(LONG_DELAY_MS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis); break; case awaitUntil: + // We shouldn't assume that nanoTime and currentTimeMillis + // use the same time source, so don't use nanoTime here. + java.util.Date delayedDate = delayedDate(timeoutMillis); assertFalse(c.awaitUntil(delayedDate(timeoutMillis))); + assertTrue(new java.util.Date().getTime() >= delayedDate.getTime()); break; default: throw new UnsupportedOperationException(); } } catch (InterruptedException ie) { threadUnexpectedException(ie); } - assertTrue(millisElapsedSince(startTime) >= timeoutMillis); } /** @@ -957,30 +971,30 @@ public class AbstractQueuedLongSynchroni */ public void testAwaitUninterruptibly() { final Mutex sync = new Mutex(); - final ConditionObject c = sync.newCondition(); + final ConditionObject condition = sync.newCondition(); final BooleanLatch pleaseInterrupt = new BooleanLatch(); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() { sync.acquire(); assertTrue(pleaseInterrupt.releaseShared(0)); - c.awaitUninterruptibly(); + condition.awaitUninterruptibly(); assertTrue(Thread.interrupted()); - assertHasWaitersLocked(sync, c, NO_THREADS); + assertHasWaitersLocked(sync, condition, NO_THREADS); sync.release(); }}); pleaseInterrupt.acquireShared(0); sync.acquire(); - assertHasWaitersLocked(sync, c, t); + assertHasWaitersLocked(sync, condition, t); sync.release(); t.interrupt(); - assertHasWaitersUnlocked(sync, c, t); - assertThreadStaysAlive(t); + assertHasWaitersUnlocked(sync, condition, t); + assertThreadBlocks(t, Thread.State.WAITING); sync.acquire(); - assertHasWaitersLocked(sync, c, t); + assertHasWaitersLocked(sync, condition, t); assertHasExclusiveQueuedThreads(sync, NO_THREADS); - c.signal(); - assertHasWaitersLocked(sync, c, NO_THREADS); + condition.signal(); + assertHasWaitersLocked(sync, condition, NO_THREADS); assertHasExclusiveQueuedThreads(sync, t); sync.release(); awaitTermination(t); @@ -1123,7 +1137,7 @@ public class AbstractQueuedLongSynchroni waitForQueuedThread(l, t); assertFalse(l.isSignalled()); - assertThreadStaysAlive(t); + assertThreadBlocks(t, Thread.State.WAITING); assertHasSharedQueuedThreads(l, t); assertTrue(l.releaseShared(0)); assertTrue(l.isSignalled()); @@ -1148,7 +1162,7 @@ public class AbstractQueuedLongSynchroni waitForQueuedThread(l, t); assertFalse(l.isSignalled()); - assertThreadStaysAlive(t); + assertThreadBlocks(t, Thread.State.TIMED_WAITING); assertTrue(l.releaseShared(0)); assertTrue(l.isSignalled()); awaitTermination(t);