--- jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java 2004/01/09 14:45:58 1.12 +++ jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java 2004/01/10 20:37:20 1.15 @@ -46,7 +46,7 @@ public class AbstractQueuedSynchronizerT if (getState() == 0) throw new IllegalMonitorStateException(); } - public ConditionObject newCondition() { return new ConditionObject(); } + public AbstractQueuedSynchronizer.ConditionObject newCondition() { return new AbstractQueuedSynchronizer.ConditionObject(); } public void lock() { acquireExclusiveUninterruptibly(1); @@ -254,7 +254,7 @@ public class AbstractQueuedSynchronizerT } /** - * timed tryAcquireExclusive is interruptible. + * acquireExclusiveNanos is interruptible. */ public void testInterruptedException2() { final Mutex lock = new Mutex(); @@ -297,9 +297,9 @@ public class AbstractQueuedSynchronizerT } /** - * acquireExclusiveTimed on a locked lock times out + * acquireExclusiveNanos on a locked lock times out */ - public void testacquireExclusiveTimed_Timeout() { + public void testAcquireExclusiveNanos_Timeout() { final Mutex lock = new Mutex(); lock.acquireExclusiveUninterruptibly(1); Thread t = new Thread(new Runnable() { @@ -322,9 +322,9 @@ public class AbstractQueuedSynchronizerT /** - * isLocked is true when locked and false when not + * getState is true when acquired and false when not */ - public void testIsLocked() { + public void testGetState() { final Mutex lock = new Mutex(); lock.acquireExclusiveUninterruptibly(1); assertTrue(lock.isLocked()); @@ -408,7 +408,7 @@ public class AbstractQueuedSynchronizerT */ public void testAwait_IllegalMonitor() { final Mutex lock = new Mutex(); - final Condition c = lock.newCondition(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); try { c.await(); shouldThrow(); @@ -425,7 +425,7 @@ public class AbstractQueuedSynchronizerT */ public void testSignal_IllegalMonitor() { final Mutex lock = new Mutex(); - final Condition c = lock.newCondition(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); try { c.signal(); shouldThrow(); @@ -442,7 +442,7 @@ public class AbstractQueuedSynchronizerT */ public void testAwaitNanos_Timeout() { final Mutex lock = new Mutex(); - final Condition c = lock.newCondition(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); try { lock.acquireExclusiveUninterruptibly(1); long t = c.awaitNanos(100); @@ -459,7 +459,7 @@ public class AbstractQueuedSynchronizerT */ public void testAwait_Timeout() { final Mutex lock = new Mutex(); - final Condition c = lock.newCondition(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); try { lock.acquireExclusiveUninterruptibly(1); assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); @@ -475,7 +475,7 @@ public class AbstractQueuedSynchronizerT */ public void testAwaitUntil_Timeout() { final Mutex lock = new Mutex(); - final Condition c = lock.newCondition(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); try { lock.acquireExclusiveUninterruptibly(1); java.util.Date d = new java.util.Date(); @@ -492,7 +492,7 @@ public class AbstractQueuedSynchronizerT */ public void testAwait() { final Mutex lock = new Mutex(); - final Condition c = lock.newCondition(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); Thread t = new Thread(new Runnable() { public void run() { try { @@ -521,10 +521,531 @@ public class AbstractQueuedSynchronizerT } + + /** + * hasWaiters throws NPE if null + */ + public void testHasWaitersNPE() { + final Mutex lock = new Mutex(); + try { + lock.hasWaiters(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength throws NPE if null + */ + public void testGetWaitQueueLengthNPE() { + final Mutex lock = new Mutex(); + try { + lock.getWaitQueueLength(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitingThreads throws NPE if null + */ + public void testGetWaitingThreadsNPE() { + final Mutex lock = new Mutex(); + try { + lock.getWaitingThreads(null); + shouldThrow(); + } catch (NullPointerException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * hasWaiters throws IAE if not owned + */ + public void testHasWaitersIAE() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (lock.newCondition()); + final Mutex lock2 = new Mutex(); + try { + lock2.hasWaiters(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * hasWaiters throws IMSE if not locked + */ + public void testHasWaitersIMSE() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (lock.newCondition()); + try { + lock.hasWaiters(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitQueueLength throws IAE if not owned + */ + public void testGetWaitQueueLengthIAE() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (lock.newCondition()); + final Mutex lock2 = new Mutex(); + try { + lock2.getWaitQueueLength(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength throws IMSE if not locked + */ + public void testGetWaitQueueLengthIMSE() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (lock.newCondition()); + try { + lock.getWaitQueueLength(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * getWaitingThreads throws IAE if not owned + */ + public void testGetWaitingThreadsIAE() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (lock.newCondition()); + final Mutex lock2 = new Mutex(); + try { + lock2.getWaitingThreads(c); + shouldThrow(); + } catch (IllegalArgumentException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitingThreads throws IMSE if not locked + */ + public void testGetWaitingThreadsIMSE() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = (lock.newCondition()); + try { + lock.getWaitingThreads(c); + shouldThrow(); + } catch (IllegalMonitorStateException success) { + } catch (Exception ex) { + unexpectedException(); + } + } + + + /** - * Latch isSignalled initially returns false, then true after release + * hasWaiters returns true when a thread is waiting, else false */ - public void testLatchIsSignalled() { + public void testHasWaiters() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.acquireExclusiveUninterruptibly(1); + threadAssertFalse(lock.hasWaiters(c)); + threadAssertEquals(0, lock.getWaitQueueLength(c)); + c.await(); + lock.releaseExclusive(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.acquireExclusiveUninterruptibly(1); + assertTrue(lock.hasWaiters(c)); + assertEquals(1, lock.getWaitQueueLength(c)); + c.signal(); + lock.releaseExclusive(1); + Thread.sleep(SHORT_DELAY_MS); + lock.acquireExclusiveUninterruptibly(1); + assertFalse(lock.hasWaiters(c)); + assertEquals(0, lock.getWaitQueueLength(c)); + lock.releaseExclusive(1); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitQueueLength returns number of waiting threads + */ + public void testGetWaitQueueLength() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + lock.acquireExclusiveUninterruptibly(1); + threadAssertFalse(lock.hasWaiters(c)); + threadAssertEquals(0, lock.getWaitQueueLength(c)); + c.await(); + lock.releaseExclusive(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + lock.acquireExclusiveUninterruptibly(1); + threadAssertTrue(lock.hasWaiters(c)); + threadAssertEquals(1, lock.getWaitQueueLength(c)); + c.await(); + lock.releaseExclusive(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.acquireExclusiveUninterruptibly(1); + assertTrue(lock.hasWaiters(c)); + assertEquals(2, lock.getWaitQueueLength(c)); + c.signalAll(); + lock.releaseExclusive(1); + Thread.sleep(SHORT_DELAY_MS); + lock.acquireExclusiveUninterruptibly(1); + assertFalse(lock.hasWaiters(c)); + assertEquals(0, lock.getWaitQueueLength(c)); + lock.releaseExclusive(1); + t1.join(SHORT_DELAY_MS); + t2.join(SHORT_DELAY_MS); + assertFalse(t1.isAlive()); + assertFalse(t2.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * getWaitingThreads returns only and all waiting threads + */ + public void testGetWaitingThreads() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + lock.acquireExclusiveUninterruptibly(1); + threadAssertTrue(lock.getWaitingThreads(c).isEmpty()); + c.await(); + lock.releaseExclusive(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + lock.acquireExclusiveUninterruptibly(1); + threadAssertFalse(lock.getWaitingThreads(c).isEmpty()); + c.await(); + lock.releaseExclusive(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + lock.acquireExclusiveUninterruptibly(1); + assertTrue(lock.getWaitingThreads(c).isEmpty()); + lock.releaseExclusive(1); + t1.start(); + Thread.sleep(SHORT_DELAY_MS); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.acquireExclusiveUninterruptibly(1); + assertTrue(lock.hasWaiters(c)); + assertTrue(lock.getWaitingThreads(c).contains(t1)); + assertTrue(lock.getWaitingThreads(c).contains(t2)); + c.signalAll(); + lock.releaseExclusive(1); + Thread.sleep(SHORT_DELAY_MS); + lock.acquireExclusiveUninterruptibly(1); + assertFalse(lock.hasWaiters(c)); + assertTrue(lock.getWaitingThreads(c).isEmpty()); + lock.releaseExclusive(1); + t1.join(SHORT_DELAY_MS); + t2.join(SHORT_DELAY_MS); + assertFalse(t1.isAlive()); + assertFalse(t2.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + + + /** + * awaitUninterruptibly doesn't abort on interrupt + */ + public void testAwaitUninterruptibly() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + lock.acquireExclusiveUninterruptibly(1); + c.awaitUninterruptibly(); + lock.releaseExclusive(1); + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + lock.acquireExclusiveUninterruptibly(1); + c.signal(); + lock.releaseExclusive(1); + assert(t.isInterrupted()); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * await is interruptible + */ + public void testAwait_Interrupt() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.acquireExclusiveUninterruptibly(1); + c.await(); + lock.releaseExclusive(1); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitNanos is interruptible + */ + public void testAwaitNanos_Interrupt() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.acquireExclusiveUninterruptibly(1); + c.awaitNanos(1000 * 1000 * 1000); // 1 sec + lock.releaseExclusive(1); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * awaitUntil is interruptible + */ + public void testAwaitUntil_Interrupt() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); + Thread t = new Thread(new Runnable() { + public void run() { + try { + lock.acquireExclusiveUninterruptibly(1); + java.util.Date d = new java.util.Date(); + c.awaitUntil(new java.util.Date(d.getTime() + 10000)); + lock.releaseExclusive(1); + threadShouldThrow(); + } + catch(InterruptedException success) { + } + } + }); + + try { + t.start(); + Thread.sleep(SHORT_DELAY_MS); + t.interrupt(); + t.join(SHORT_DELAY_MS); + assertFalse(t.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + /** + * signalAll wakes up all threads + */ + public void testSignalAll() { + final Mutex lock = new Mutex(); + final AbstractQueuedSynchronizer.ConditionObject c = lock.newCondition(); + Thread t1 = new Thread(new Runnable() { + public void run() { + try { + lock.acquireExclusiveUninterruptibly(1); + c.await(); + lock.releaseExclusive(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + Thread t2 = new Thread(new Runnable() { + public void run() { + try { + lock.acquireExclusiveUninterruptibly(1); + c.await(); + lock.releaseExclusive(1); + } + catch(InterruptedException e) { + threadUnexpectedException(); + } + } + }); + + try { + t1.start(); + t2.start(); + Thread.sleep(SHORT_DELAY_MS); + lock.acquireExclusiveUninterruptibly(1); + c.signalAll(); + lock.releaseExclusive(1); + t1.join(SHORT_DELAY_MS); + t2.join(SHORT_DELAY_MS); + assertFalse(t1.isAlive()); + assertFalse(t2.isAlive()); + } + catch (Exception ex) { + unexpectedException(); + } + } + + + /** + * toString indicates current state + */ + public void testToString() { + Mutex lock = new Mutex(); + String us = lock.toString(); + assertTrue(us.indexOf("State = 0") >= 0); + lock.acquireExclusiveUninterruptibly(1); + String ls = lock.toString(); + assertTrue(ls.indexOf("State = 1") >= 0); + } + + /** + * A serialized AQS deserializes with current state + */ + public void testSerialization() { + Mutex l = new Mutex(); + l.acquireExclusiveUninterruptibly(1); + assertTrue(l.isLocked()); + + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); + ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); + out.writeObject(l); + out.close(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); + ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); + Mutex r = (Mutex) in.readObject(); + assertTrue(r.isLocked()); + } catch(Exception e){ + e.printStackTrace(); + unexpectedException(); + } + } + + + /** + * tryReleaseShared setting state changes getState + */ + public void testGetStateWithReleaseShared() { final BooleanLatch l = new BooleanLatch(); assertFalse(l.isSignalled()); l.releaseShared(0); @@ -534,7 +1055,7 @@ public class AbstractQueuedSynchronizerT /** * release and has no effect when already signalled */ - public void testLatchBoolean() { + public void testReleaseShared() { final BooleanLatch l = new BooleanLatch(); assertFalse(l.isSignalled()); l.releaseShared(0); @@ -546,7 +1067,7 @@ public class AbstractQueuedSynchronizerT /** * acquireSharedInterruptibly returns after release, but not before */ - public void testLatchAcquireSharedInterruptibly() { + public void testAcquireSharedInterruptibly() { final BooleanLatch l = new BooleanLatch(); Thread t = new Thread(new Runnable() { @@ -576,7 +1097,7 @@ public class AbstractQueuedSynchronizerT /** * acquireSharedTimed returns after release */ - public void testLatchTimedacquireSharedInterruptibly() { + public void testAsquireSharedTimed() { final BooleanLatch l = new BooleanLatch(); Thread t = new Thread(new Runnable() { @@ -606,7 +1127,7 @@ public class AbstractQueuedSynchronizerT /** * acquireSharedInterruptibly throws IE if interrupted before released */ - public void testLatchAcquireSharedInterruptibly_InterruptedException() { + public void testAcquireSharedInterruptibly_InterruptedException() { final BooleanLatch l = new BooleanLatch(); Thread t = new Thread(new Runnable() { public void run() { @@ -630,7 +1151,7 @@ public class AbstractQueuedSynchronizerT /** * acquireSharedTimed throws IE if interrupted before released */ - public void testLatchTimedAwait_InterruptedException() { + public void testAcquireSharedNanos_InterruptedException() { final BooleanLatch l = new BooleanLatch(); Thread t = new Thread(new Runnable() { public void run() { @@ -655,7 +1176,7 @@ public class AbstractQueuedSynchronizerT /** * acquireSharedTimed times out if not released before timeout */ - public void testLatchAwaitTimeout() { + public void testAcquireSharedNanos_Timeout() { final BooleanLatch l = new BooleanLatch(); Thread t = new Thread(new Runnable() { public void run() { @@ -676,5 +1197,6 @@ public class AbstractQueuedSynchronizerT unexpectedException(); } } + }