--- jsr166/src/test/tck/SynchronousQueueTest.java 2011/03/15 19:47:07 1.31 +++ jsr166/src/test/tck/SynchronousQueueTest.java 2021/01/27 01:57:24 1.69 @@ -6,11 +6,20 @@ * Pat Fisher, Mike Judd. */ -import junit.framework.*; -import java.util.*; -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import java.io.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.SynchronousQueue; + +import junit.framework.Test; public class SynchronousQueueTest extends JSR166TestCase { @@ -27,7 +36,7 @@ public class SynchronousQueueTest extend } public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); + main(suite(), args); } public static Test suite() { @@ -39,382 +48,274 @@ public class SynchronousQueueTest extend /** * Any SynchronousQueue is both empty and full */ - public void testEmptyFull(SynchronousQueue q) { + public void testEmptyFull() { testEmptyFull(false); } + public void testEmptyFull_fair() { testEmptyFull(true); } + public void testEmptyFull(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); assertTrue(q.isEmpty()); - assertEquals(0, q.size()); - assertEquals(0, q.remainingCapacity()); + mustEqual(0, q.size()); + mustEqual(0, q.remainingCapacity()); assertFalse(q.offer(zero)); } /** - * A non-fair SynchronousQueue is both empty and full - */ - public void testEmptyFull() { - testEmptyFull(new SynchronousQueue()); - } - - /** - * A fair SynchronousQueue is both empty and full - */ - public void testFairEmptyFull() { - testEmptyFull(new SynchronousQueue(true)); - } - - /** - * offer(null) throws NPE - */ - public void testOfferNull() { - try { - SynchronousQueue q = new SynchronousQueue(); - q.offer(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * add(null) throws NPE - */ - public void testAddNull() { - try { - SynchronousQueue q = new SynchronousQueue(); - q.add(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** * offer fails if no active taker */ - public void testOffer() { - SynchronousQueue q = new SynchronousQueue(); + public void testOffer() { testOffer(false); } + public void testOffer_fair() { testOffer(true); } + public void testOffer(boolean fair) { + SynchronousQueue q = new SynchronousQueue<>(fair); assertFalse(q.offer(one)); } /** - * add throws ISE if no active taker + * add throws IllegalStateException if no active taker */ - public void testAdd() { + public void testAdd() { testAdd(false); } + public void testAdd_fair() { testAdd(true); } + public void testAdd(boolean fair) { + SynchronousQueue q = new SynchronousQueue<>(fair); + mustEqual(0, q.remainingCapacity()); try { - SynchronousQueue q = new SynchronousQueue(); - assertEquals(0, q.remainingCapacity()); q.add(one); shouldThrow(); } catch (IllegalStateException success) {} } /** - * addAll(null) throws NPE + * addAll(this) throws IllegalArgumentException */ - public void testAddAll1() { + public void testAddAll_self() { testAddAll_self(false); } + public void testAddAll_self_fair() { testAddAll_self(true); } + public void testAddAll_self(boolean fair) { + SynchronousQueue q = new SynchronousQueue<>(fair); try { - SynchronousQueue q = new SynchronousQueue(); - q.addAll(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll(this) throws IAE - */ - public void testAddAllSelf() { - try { - SynchronousQueue q = new SynchronousQueue(); q.addAll(q); shouldThrow(); } catch (IllegalArgumentException success) {} } - /** - * addAll of a collection with null elements throws NPE - */ - public void testAddAll2() { - try { - SynchronousQueue q = new SynchronousQueue(); - Integer[] ints = new Integer[1]; - q.addAll(Arrays.asList(ints)); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * addAll throws ISE if no active taker + /**S + * addAll throws IllegalStateException if no active taker */ - public void testAddAll4() { + public void testAddAll_ISE() { testAddAll_ISE(false); } + public void testAddAll_ISE_fair() { testAddAll_ISE(true); } + public void testAddAll_ISE(boolean fair) { + SynchronousQueue q = new SynchronousQueue<>(fair); + Item[] items = seqItems(1); + Collection coll = Arrays.asList(items); try { - SynchronousQueue q = new SynchronousQueue(); - Integer[] ints = new Integer[1]; - for (int i = 0; i < 1; ++i) - ints[i] = new Integer(i); - q.addAll(Arrays.asList(ints)); + q.addAll(coll); shouldThrow(); } catch (IllegalStateException success) {} } /** - * put(null) throws NPE - */ - public void testPutNull() throws InterruptedException { - try { - SynchronousQueue q = new SynchronousQueue(); - q.put(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** * put blocks interruptibly if no active taker */ - public void testBlockingPut() throws InterruptedException { - Thread t = new Thread(new CheckedInterruptedRunnable() { + public void testBlockingPut() { testBlockingPut(false); } + public void testBlockingPut_fair() { testBlockingPut(true); } + public void testBlockingPut(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - SynchronousQueue q = new SynchronousQueue(); - q.put(zero); - }}); - - t.start(); - Thread.sleep(SHORT_DELAY_MS); - t.interrupt(); - t.join(); - } + Thread.currentThread().interrupt(); + try { + q.put(ninetynine); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); - /** - * put blocks waiting for take - */ - public void testPutWithTake() throws InterruptedException { - final SynchronousQueue q = new SynchronousQueue(); - Thread t = new Thread(new CheckedRunnable() { - public void realRun() throws InterruptedException { - int added = 0; + pleaseInterrupt.countDown(); try { - while (true) { - q.put(added); - ++added; - } - } catch (InterruptedException success) { - assertEquals(1, added); - } + q.put(ninetynine); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); }}); - t.start(); - Thread.sleep(SHORT_DELAY_MS); - assertEquals(0, q.take()); - Thread.sleep(SHORT_DELAY_MS); + await(pleaseInterrupt); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); t.interrupt(); - t.join(); + awaitTermination(t); + mustEqual(0, q.remainingCapacity()); } /** - * timed offer times out if elements not taken + * put blocks interruptibly waiting for take */ - public void testTimedOffer(final SynchronousQueue q) - throws InterruptedException { + public void testPutWithTake() { testPutWithTake(false); } + public void testPutWithTake_fair() { testPutWithTake(true); } + public void testPutWithTake(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + final CountDownLatch pleaseTake = new CountDownLatch(1); final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long t0 = System.nanoTime(); - assertFalse(q.offer(new Object(), SHORT_DELAY_MS, MILLISECONDS)); - assertTrue(millisElapsedSince(t0) >= SHORT_DELAY_MS); + pleaseTake.countDown(); + q.put(one); + + Thread.currentThread().interrupt(); + try { + q.put(ninetynine); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + pleaseInterrupt.countDown(); - t0 = System.nanoTime(); try { - q.offer(new Object(), LONG_DELAY_MS, MILLISECONDS); + q.put(ninetynine); shouldThrow(); } catch (InterruptedException success) {} - assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS); + assertFalse(Thread.interrupted()); }}); - assertTrue(pleaseInterrupt.await(MEDIUM_DELAY_MS, MILLISECONDS)); - t.interrupt(); - awaitTermination(t, MEDIUM_DELAY_MS); - } + await(pleaseTake); + mustEqual(0, q.remainingCapacity()); + try { assertSame(one, q.take()); } + catch (InterruptedException e) { threadUnexpectedException(e); } - /** - * timed offer times out if elements not taken - */ - public void testTimedOffer() throws InterruptedException { - testTimedOffer(new SynchronousQueue()); + await(pleaseInterrupt); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); + mustEqual(0, q.remainingCapacity()); } /** * timed offer times out if elements not taken */ - public void testFairTimedOffer() throws InterruptedException { - testTimedOffer(new SynchronousQueue(true)); - } - - /** - * put blocks interruptibly if no active taker - */ - public void testFairBlockingPut() throws InterruptedException { - Thread t = new Thread(new CheckedInterruptedRunnable() { + public void testTimedOffer() { + final boolean fair = randomBoolean(); + final SynchronousQueue q = new SynchronousQueue<>(fair); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - SynchronousQueue q = new SynchronousQueue(true); - q.put(zero); - }}); + long startTime = System.nanoTime(); - t.start(); - Thread.sleep(SHORT_DELAY_MS); - t.interrupt(); - t.join(); - } + assertFalse(q.offer(zero, timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); - /** - * put blocks waiting for take - */ - public void testFairPutWithTake() throws InterruptedException { - final SynchronousQueue q = new SynchronousQueue(true); - Thread t = new Thread(new CheckedRunnable() { - public void realRun() throws InterruptedException { - int added = 0; + Thread.currentThread().interrupt(); try { - while (true) { - q.put(added); - ++added; - } - } catch (InterruptedException success) { - assertEquals(1, added); - } - }}); - - t.start(); - Thread.sleep(SHORT_DELAY_MS); - assertEquals(0, q.take()); - Thread.sleep(SHORT_DELAY_MS); - t.interrupt(); - t.join(); - } + q.offer(one, randomTimeout(), randomTimeUnit()); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); - /** - * take blocks interruptibly when empty - */ - public void testFairTakeFromEmpty() throws InterruptedException { - final SynchronousQueue q = new SynchronousQueue(true); - Thread t = new Thread(new CheckedInterruptedRunnable() { - public void realRun() throws InterruptedException { - q.take(); + pleaseInterrupt.countDown(); + try { + q.offer(two, LONGER_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); }}); - t.start(); - Thread.sleep(SHORT_DELAY_MS); + await(pleaseInterrupt); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); - t.join(); + awaitTermination(t); } /** * poll return null if no active putter */ - public void testPoll() { - SynchronousQueue q = new SynchronousQueue(); + public void testPoll() { testPoll(false); } + public void testPoll_fair() { testPoll(true); } + public void testPoll(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); assertNull(q.poll()); } /** * timed poll with zero timeout times out if no active putter */ - public void testTimedPoll0() throws InterruptedException { - SynchronousQueue q = new SynchronousQueue(); - assertNull(q.poll(0, MILLISECONDS)); + public void testTimedPoll0() { testTimedPoll0(false); } + public void testTimedPoll0_fair() { testTimedPoll0(true); } + public void testTimedPoll0(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + try { assertNull(q.poll(0, MILLISECONDS)); } + catch (InterruptedException e) { threadUnexpectedException(e); } } /** * timed poll with nonzero timeout times out if no active putter */ - public void testTimedPoll() throws InterruptedException { - SynchronousQueue q = new SynchronousQueue(); - long t0 = System.nanoTime(); - assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS)); - assertTrue(millisElapsedSince(t0) >= SHORT_DELAY_MS); - } - - /** - * Interrupted timed poll throws InterruptedException instead of - * returning timeout status - */ - public void testInterruptedTimedPoll(final SynchronousQueue q) - throws InterruptedException { - final CountDownLatch threadStarted = new CountDownLatch(1); - Thread t = newStartedThread(new CheckedRunnable() { - public void realRun() throws InterruptedException { - long t0 = System.nanoTime(); - threadStarted.countDown(); - try { - q.poll(LONG_DELAY_MS, MILLISECONDS); - shouldThrow(); - } catch (InterruptedException success) {} - assertTrue(millisElapsedSince(t0) >= SHORT_DELAY_MS); - assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS); - }}); - - threadStarted.await(); - Thread.sleep(SHORT_DELAY_MS); - t.interrupt(); - awaitTermination(t, MEDIUM_DELAY_MS); - } - - /** - * Interrupted timed poll throws InterruptedException instead of - * returning timeout status - */ - public void testInterruptedTimedPoll() throws InterruptedException { - testInterruptedTimedPoll(new SynchronousQueue()); - } - - /** - * Interrupted timed poll throws InterruptedException instead of - * returning timeout status - */ - public void testFairInterruptedTimedPoll() throws InterruptedException { - testInterruptedTimedPoll(new SynchronousQueue(true)); + public void testTimedPoll() { + final boolean fair = randomBoolean(); + final SynchronousQueue q = new SynchronousQueue<>(fair); + final long startTime = System.nanoTime(); + try { assertNull(q.poll(timeoutMillis(), MILLISECONDS)); } + catch (InterruptedException e) { threadUnexpectedException(e); } + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); } /** * timed poll before a delayed offer times out, returning null; * after offer succeeds; on interruption throws */ - public void testFairTimedPollWithOffer() throws InterruptedException { - final SynchronousQueue q = new SynchronousQueue(true); + public void testTimedPollWithOffer() { + final boolean fair = randomBoolean(); + final SynchronousQueue q = new SynchronousQueue<>(fair); final CountDownLatch pleaseOffer = new CountDownLatch(1); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - long t0 = System.nanoTime(); - assertNull(q.poll(SHORT_DELAY_MS, MILLISECONDS)); - assertTrue(millisElapsedSince(t0) >= SHORT_DELAY_MS); + long startTime = System.nanoTime(); + assertNull(q.poll(timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); pleaseOffer.countDown(); - t0 = System.nanoTime(); + startTime = System.nanoTime(); assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS)); - assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS); - t0 = System.nanoTime(); + Thread.currentThread().interrupt(); + try { + q.poll(randomTimeout(), randomTimeUnit()); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); try { q.poll(LONG_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (InterruptedException success) {} - assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS); + assertFalse(Thread.interrupted()); + + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); }}); - assertTrue(pleaseOffer.await(MEDIUM_DELAY_MS, MILLISECONDS)); - long t0 = System.nanoTime(); - assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); - assertTrue(millisElapsedSince(t0) < MEDIUM_DELAY_MS); + await(pleaseOffer); + long startTime = System.nanoTime(); + try { assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); } + catch (InterruptedException e) { threadUnexpectedException(e); } + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); + await(pleaseInterrupt); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); t.interrupt(); - awaitTermination(t, MEDIUM_DELAY_MS); + awaitTermination(t); } /** * peek() returns null if no active putter */ - public void testPeek() { - SynchronousQueue q = new SynchronousQueue(); + public void testPeek() { testPeek(false); } + public void testPeek_fair() { testPeek(true); } + public void testPeek(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); assertNull(q.peek()); } /** - * element() throws NSEE if no active putter + * element() throws NoSuchElementException if no active putter */ - public void testElement() { - SynchronousQueue q = new SynchronousQueue(); + public void testElement() { testElement(false); } + public void testElement_fair() { testElement(true); } + public void testElement(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); try { q.element(); shouldThrow(); @@ -422,10 +323,12 @@ public class SynchronousQueueTest extend } /** - * remove() throws NSEE if no active putter + * remove() throws NoSuchElementException if no active putter */ - public void testRemove() { - SynchronousQueue q = new SynchronousQueue(); + public void testRemove() { testRemove(false); } + public void testRemove_fair() { testRemove(true); } + public void testRemove(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); try { q.remove(); shouldThrow(); @@ -433,27 +336,22 @@ public class SynchronousQueueTest extend } /** - * remove(x) returns false - */ - public void testRemoveElement() { - SynchronousQueue q = new SynchronousQueue(); - assertFalse(q.remove(zero)); - assertTrue(q.isEmpty()); - } - - /** * contains returns false */ - public void testContains() { - SynchronousQueue q = new SynchronousQueue(); + public void testContains() { testContains(false); } + public void testContains_fair() { testContains(true); } + public void testContains(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); assertFalse(q.contains(zero)); } /** * clear ensures isEmpty */ - public void testClear() { - SynchronousQueue q = new SynchronousQueue(); + public void testClear() { testClear(false); } + public void testClear_fair() { testClear(true); } + public void testClear(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); q.clear(); assertTrue(q.isEmpty()); } @@ -461,86 +359,104 @@ public class SynchronousQueueTest extend /** * containsAll returns false unless empty */ - public void testContainsAll() { - SynchronousQueue q = new SynchronousQueue(); - Integer[] empty = new Integer[0]; + public void testContainsAll() { testContainsAll(false); } + public void testContainsAll_fair() { testContainsAll(true); } + public void testContainsAll(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + Item[] empty = new Item[0]; assertTrue(q.containsAll(Arrays.asList(empty))); - Integer[] ints = new Integer[1]; ints[0] = zero; - assertFalse(q.containsAll(Arrays.asList(ints))); + Item[] items = new Item[1]; items[0] = zero; + assertFalse(q.containsAll(Arrays.asList(items))); } /** * retainAll returns false */ - public void testRetainAll() { - SynchronousQueue q = new SynchronousQueue(); - Integer[] empty = new Integer[0]; + public void testRetainAll() { testRetainAll(false); } + public void testRetainAll_fair() { testRetainAll(true); } + public void testRetainAll(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + Item[] empty = new Item[0]; assertFalse(q.retainAll(Arrays.asList(empty))); - Integer[] ints = new Integer[1]; ints[0] = zero; - assertFalse(q.retainAll(Arrays.asList(ints))); + Item[] items = new Item[1]; items[0] = zero; + assertFalse(q.retainAll(Arrays.asList(items))); } /** * removeAll returns false */ - public void testRemoveAll() { - SynchronousQueue q = new SynchronousQueue(); - Integer[] empty = new Integer[0]; + public void testRemoveAll() { testRemoveAll(false); } + public void testRemoveAll_fair() { testRemoveAll(true); } + public void testRemoveAll(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + Item[] empty = new Item[0]; assertFalse(q.removeAll(Arrays.asList(empty))); - Integer[] ints = new Integer[1]; ints[0] = zero; - assertFalse(q.containsAll(Arrays.asList(ints))); + Item[] items = new Item[1]; items[0] = zero; + assertFalse(q.containsAll(Arrays.asList(items))); } - /** * toArray is empty */ - public void testToArray() { - SynchronousQueue q = new SynchronousQueue(); + public void testToArray() { testToArray(false); } + public void testToArray_fair() { testToArray(true); } + public void testToArray(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); Object[] o = q.toArray(); - assertEquals(o.length, 0); + mustEqual(0, o.length); } /** - * toArray(a) is nulled at position 0 + * toArray(Item array) returns its argument with the first + * element (if present) nulled out */ - public void testToArray2() { - SynchronousQueue q = new SynchronousQueue(); - Integer[] ints = new Integer[1]; - assertNull(ints[0]); + public void testToArray2() { testToArray2(false); } + public void testToArray2_fair() { testToArray2(true); } + public void testToArray2(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + Item[] a; + + a = new Item[0]; + assertSame(a, q.toArray(a)); + + a = new Item[3]; + Arrays.fill(a, fortytwo); + assertSame(a, q.toArray(a)); + assertNull(a[0]); + for (int i = 1; i < a.length; i++) + mustEqual(42, a[i]); } /** * toArray(null) throws NPE */ - public void testToArray_BadArg() { - SynchronousQueue q = new SynchronousQueue(); + public void testToArray_null() { testToArray_null(false); } + public void testToArray_null_fair() { testToArray_null(true); } + public void testToArray_null(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); try { - Object o[] = q.toArray(null); + Object[] unused = q.toArray((Object[])null); shouldThrow(); } catch (NullPointerException success) {} } - /** * iterator does not traverse any elements */ - public void testIterator() { - SynchronousQueue q = new SynchronousQueue(); - Iterator it = q.iterator(); - assertFalse(it.hasNext()); - try { - Object x = it.next(); - shouldThrow(); - } catch (NoSuchElementException success) {} + public void testIterator() { testIterator(false); } + public void testIterator_fair() { testIterator(true); } + public void testIterator(boolean fair) { + assertIteratorExhausted(new SynchronousQueue(fair).iterator()); } /** - * iterator remove throws ISE + * iterator remove throws IllegalStateException */ - public void testIteratorRemove() { - SynchronousQueue q = new SynchronousQueue(); - Iterator it = q.iterator(); + public void testIteratorRemove() { testIteratorRemove(false); } + public void testIteratorRemove_fair() { testIteratorRemove(true); } + public void testIteratorRemove(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + Iterator it = q.iterator(); try { it.remove(); shouldThrow(); @@ -550,179 +466,164 @@ public class SynchronousQueueTest extend /** * toString returns a non-null string */ - public void testToString() { - SynchronousQueue q = new SynchronousQueue(); + public void testToString() { testToString(false); } + public void testToString_fair() { testToString(true); } + public void testToString(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); String s = q.toString(); assertNotNull(s); } - /** * offer transfers elements across Executor tasks */ - public void testOfferInExecutor() { - final SynchronousQueue q = new SynchronousQueue(); - ExecutorService executor = Executors.newFixedThreadPool(2); - - executor.execute(new CheckedRunnable() { - public void realRun() throws InterruptedException { - assertFalse(q.offer(one)); - assertTrue(q.offer(one, MEDIUM_DELAY_MS, MILLISECONDS)); - assertEquals(0, q.remainingCapacity()); - }}); - - executor.execute(new CheckedRunnable() { - public void realRun() throws InterruptedException { - Thread.sleep(SMALL_DELAY_MS); - assertSame(one, q.take()); - }}); - - joinPool(executor); - } - - /** - * poll retrieves elements across Executor threads - */ - public void testPollInExecutor() { - final SynchronousQueue q = new SynchronousQueue(); - ExecutorService executor = Executors.newFixedThreadPool(2); - executor.execute(new CheckedRunnable() { - public void realRun() throws InterruptedException { - assertNull(q.poll()); - assertSame(one, q.poll(MEDIUM_DELAY_MS, MILLISECONDS)); - assertTrue(q.isEmpty()); - }}); - - executor.execute(new CheckedRunnable() { - public void realRun() throws InterruptedException { - Thread.sleep(SHORT_DELAY_MS); - q.put(one); - }}); - - joinPool(executor); - } - - /** - * a deserialized serialized queue is usable - */ - public void testSerialization() throws Exception { - SynchronousQueue q = new SynchronousQueue(); - ByteArrayOutputStream bout = new ByteArrayOutputStream(10000); - ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(bout)); - out.writeObject(q); - out.close(); - - ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); - ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(bin)); - SynchronousQueue r = (SynchronousQueue)in.readObject(); - assertEquals(q.size(), r.size()); - while (!q.isEmpty()) - assertEquals(q.remove(), r.remove()); + public void testOfferInExecutor() { testOfferInExecutor(false); } + public void testOfferInExecutor_fair() { testOfferInExecutor(true); } + public void testOfferInExecutor(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + final CheckedBarrier threadsStarted = new CheckedBarrier(2); + final ExecutorService executor = Executors.newFixedThreadPool(2); + try (PoolCleaner cleaner = cleaner(executor)) { + + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + assertFalse(q.offer(one)); + threadsStarted.await(); + assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS)); + mustEqual(0, q.remainingCapacity()); + }}); + + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + threadsStarted.await(); + assertSame(one, q.take()); + }}); + } } /** - * drainTo(null) throws NPE + * timed poll retrieves elements across Executor threads */ - public void testDrainToNull() { - SynchronousQueue q = new SynchronousQueue(); - try { - q.drainTo(null); - shouldThrow(); - } catch (NullPointerException success) {} + public void testPollInExecutor() { testPollInExecutor(false); } + public void testPollInExecutor_fair() { testPollInExecutor(true); } + public void testPollInExecutor(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + final CheckedBarrier threadsStarted = new CheckedBarrier(2); + final ExecutorService executor = Executors.newFixedThreadPool(2); + try (PoolCleaner cleaner = cleaner(executor)) { + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + assertNull(q.poll()); + threadsStarted.await(); + assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS)); + assertTrue(q.isEmpty()); + }}); + + executor.execute(new CheckedRunnable() { + public void realRun() throws InterruptedException { + threadsStarted.await(); + q.put(one); + }}); + } } /** - * drainTo(this) throws IAE + * a deserialized/reserialized queue is usable */ - public void testDrainToSelf() { - SynchronousQueue q = new SynchronousQueue(); - try { - q.drainTo(q); - shouldThrow(); - } catch (IllegalArgumentException success) {} + public void testSerialization() { + final SynchronousQueue x = new SynchronousQueue<>(); + final SynchronousQueue y = new SynchronousQueue<>(false); + final SynchronousQueue z = new SynchronousQueue<>(true); + assertSerialEquals(x, y); + assertNotSerialEquals(x, z); + SynchronousQueue[] rqs = { x, y, z }; + @SuppressWarnings("unchecked") + SynchronousQueue[] qs = (SynchronousQueue[])rqs; + for (SynchronousQueue q : qs) { + SynchronousQueue clone = serialClone(q); + assertNotSame(q, clone); + assertSerialEquals(q, clone); + assertTrue(clone.isEmpty()); + mustEqual(0, clone.size()); + mustEqual(0, clone.remainingCapacity()); + assertFalse(clone.offer(zero)); + } } /** * drainTo(c) of empty queue doesn't transfer elements */ - public void testDrainTo() { - SynchronousQueue q = new SynchronousQueue(); - ArrayList l = new ArrayList(); + public void testDrainTo() { testDrainTo(false); } + public void testDrainTo_fair() { testDrainTo(true); } + public void testDrainTo(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + ArrayList l = new ArrayList<>(); q.drainTo(l); - assertEquals(q.size(), 0); - assertEquals(l.size(), 0); + mustEqual(0, q.size()); + mustEqual(0, l.size()); } /** * drainTo empties queue, unblocking a waiting put. */ - public void testDrainToWithActivePut() throws InterruptedException { - final SynchronousQueue q = new SynchronousQueue(); - Thread t = new Thread(new CheckedRunnable() { + public void testDrainToWithActivePut() { testDrainToWithActivePut(false); } + public void testDrainToWithActivePut_fair() { testDrainToWithActivePut(true); } + public void testDrainToWithActivePut(boolean fair) { + final SynchronousQueue q = new SynchronousQueue<>(fair); + Thread t = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { - q.put(new Integer(1)); + q.put(one); }}); - t.start(); - ArrayList l = new ArrayList(); - Thread.sleep(SHORT_DELAY_MS); - q.drainTo(l); - assertTrue(l.size() <= 1); - if (l.size() > 0) - assertEquals(l.get(0), new Integer(1)); - t.join(); - assertTrue(l.size() <= 1); - } - - /** - * drainTo(null, n) throws NPE - */ - public void testDrainToNullN() { - SynchronousQueue q = new SynchronousQueue(); - try { - q.drainTo(null, 0); - shouldThrow(); - } catch (NullPointerException success) {} - } - - /** - * drainTo(this, n) throws IAE - */ - public void testDrainToSelfN() { - SynchronousQueue q = new SynchronousQueue(); - try { - q.drainTo(q, 0); - shouldThrow(); - } catch (IllegalArgumentException success) {} + ArrayList l = new ArrayList<>(); + long startTime = System.nanoTime(); + while (l.isEmpty()) { + q.drainTo(l); + if (millisElapsedSince(startTime) > LONG_DELAY_MS) + fail("timed out"); + Thread.yield(); + } + mustEqual(1, l.size()); + assertSame(one, l.get(0)); + awaitTermination(t); } /** * drainTo(c, n) empties up to n elements of queue into c */ public void testDrainToN() throws InterruptedException { - final SynchronousQueue q = new SynchronousQueue(); - Thread t1 = new Thread(new CheckedRunnable() { + final SynchronousQueue q = new SynchronousQueue<>(); + Thread t1 = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { q.put(one); }}); - Thread t2 = new Thread(new CheckedRunnable() { + Thread t2 = newStartedThread(new CheckedRunnable() { public void realRun() throws InterruptedException { q.put(two); }}); - t1.start(); - t2.start(); - ArrayList l = new ArrayList(); - Thread.sleep(SHORT_DELAY_MS); - q.drainTo(l, 1); - assertEquals(1, l.size()); - q.drainTo(l, 1); - assertEquals(2, l.size()); + ArrayList l = new ArrayList<>(); + int drained; + while ((drained = q.drainTo(l, 1)) == 0) Thread.yield(); + mustEqual(1, drained); + mustEqual(1, l.size()); + while ((drained = q.drainTo(l, 1)) == 0) Thread.yield(); + mustEqual(1, drained); + mustEqual(2, l.size()); assertTrue(l.contains(one)); assertTrue(l.contains(two)); - t1.join(); - t2.join(); + awaitTermination(t1); + awaitTermination(t2); + } + + /** + * remove(null), contains(null) always return false + */ + public void testNeverContainsNull() { + Collection q = new SynchronousQueue<>(); + assertFalse(q.contains(null)); + assertFalse(q.remove(null)); } }