--- jsr166/src/test/tck/CountDownLatchTest.java 2003/12/27 19:26:43 1.6 +++ jsr166/src/test/tck/CountDownLatchTest.java 2019/09/05 21:33:55 1.29 @@ -1,189 +1,202 @@ /* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain - * Other contributors include Andrew Wright, Jeffrey Hayes, - * Pat Fisher, Mike Judd. + * http://creativecommons.org/publicdomain/zero/1.0/ + * Other contributors include Andrew Wright, Jeffrey Hayes, + * Pat Fisher, Mike Judd. */ -import junit.framework.*; -import java.util.*; -import java.util.concurrent.*; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ThreadLocalRandom; + +import junit.framework.Test; +import junit.framework.TestSuite; public class CountDownLatchTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run (suite()); + main(suite(), args); } public static Test suite() { - return new TestSuite(CountDownLatchTest.class); + return new TestSuite(CountDownLatchTest.class); } /** - * negative constructor argument throws IAE + * negative constructor argument throws IllegalArgumentException */ public void testConstructor() { try { new CountDownLatch(-1); shouldThrow(); - } catch(IllegalArgumentException success){} + } catch (IllegalArgumentException success) {} } /** * getCount returns initial count and decreases after countDown */ public void testGetCount() { - final CountDownLatch l = new CountDownLatch(2); - assertEquals(2, l.getCount()); - l.countDown(); - assertEquals(1, l.getCount()); + final CountDownLatch l = new CountDownLatch(2); + assertEquals(2, l.getCount()); + l.countDown(); + assertEquals(1, l.getCount()); } /** * countDown decrements count when positive and has no effect when zero */ public void testCountDown() { - final CountDownLatch l = new CountDownLatch(1); - assertEquals(1, l.getCount()); - l.countDown(); - assertEquals(0, l.getCount()); - l.countDown(); - assertEquals(0, l.getCount()); + final CountDownLatch l = new CountDownLatch(1); + assertEquals(1, l.getCount()); + l.countDown(); + assertEquals(0, l.getCount()); + l.countDown(); + assertEquals(0, l.getCount()); } /** * await returns after countDown to zero, but not before */ public void testAwait() { - final CountDownLatch l = new CountDownLatch(2); + final CountDownLatch l = new CountDownLatch(2); + final CountDownLatch pleaseCountDown = new CountDownLatch(1); - Thread t = new Thread(new Runnable() { - public void run() { - try { - threadAssertTrue(l.getCount() > 0); - l.await(); - threadAssertTrue(l.getCount() == 0); - } catch(InterruptedException e){ - threadUnexpectedException(); - } - } - }); - t.start(); - try { - assertEquals(l.getCount(), 2); - Thread.sleep(SHORT_DELAY_MS); - l.countDown(); - assertEquals(l.getCount(), 1); - l.countDown(); - assertEquals(l.getCount(), 0); - t.join(); - } catch (InterruptedException e){ - unexpectedException(); - } + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + assertEquals(2, l.getCount()); + pleaseCountDown.countDown(); + l.await(); + assertEquals(0, l.getCount()); + }}); + + await(pleaseCountDown); + assertEquals(2, l.getCount()); + l.countDown(); + assertEquals(1, l.getCount()); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); + l.countDown(); + assertEquals(0, l.getCount()); + awaitTermination(t); } - /** * timed await returns after countDown to zero */ public void testTimedAwait() { - final CountDownLatch l = new CountDownLatch(2); + final CountDownLatch l = new CountDownLatch(2); + final CountDownLatch pleaseCountDown = new CountDownLatch(1); - Thread t = new Thread(new Runnable() { - public void run() { - try { - threadAssertTrue(l.getCount() > 0); - threadAssertTrue(l.await(SMALL_DELAY_MS, TimeUnit.MILLISECONDS)); - } catch(InterruptedException e){ - threadUnexpectedException(); - } - } - }); - t.start(); - try { - assertEquals(l.getCount(), 2); - Thread.sleep(SHORT_DELAY_MS); - l.countDown(); - assertEquals(l.getCount(), 1); - l.countDown(); - assertEquals(l.getCount(), 0); - t.join(); - } catch (InterruptedException e){ - unexpectedException(); - } + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + assertEquals(2, l.getCount()); + pleaseCountDown.countDown(); + assertTrue(l.await(LONG_DELAY_MS, MILLISECONDS)); + assertEquals(0, l.getCount()); + }}); + + await(pleaseCountDown); + assertEquals(2, l.getCount()); + l.countDown(); + assertEquals(1, l.getCount()); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); + l.countDown(); + assertEquals(0, l.getCount()); + awaitTermination(t); } - + /** - * await throws IE if interrupted before counted down + * await throws InterruptedException if interrupted before counted down */ - public void testAwait_InterruptedException() { + public void testAwait_Interruptible() { final CountDownLatch l = new CountDownLatch(1); - Thread t = new Thread(new Runnable() { - public void run() { - try { - threadAssertTrue(l.getCount() > 0); - l.await(); - threadShouldThrow(); - } catch(InterruptedException success){} - } - }); - t.start(); - try { - assertEquals(l.getCount(), 1); - t.interrupt(); - t.join(); - } catch (InterruptedException e){ - unexpectedException(); - } + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + Thread.currentThread().interrupt(); + try { + l.await(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + l.await(); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + assertEquals(1, l.getCount()); + }}); + + await(pleaseInterrupt); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING); + t.interrupt(); + awaitTermination(t); } /** - * timed await throws IE if interrupted before counted down - */ - public void testTimedAwait_InterruptedException() { - final CountDownLatch l = new CountDownLatch(1); - Thread t = new Thread(new Runnable() { - public void run() { - try { - threadAssertTrue(l.getCount() > 0); - l.await(MEDIUM_DELAY_MS, TimeUnit.MILLISECONDS); - threadShouldThrow(); - } catch(InterruptedException success){} - } - }); - t.start(); - try { - Thread.sleep(SHORT_DELAY_MS); - assertEquals(l.getCount(), 1); - t.interrupt(); - t.join(); - } catch (InterruptedException e){ - unexpectedException(); - } + * timed await throws InterruptedException if interrupted before counted down + */ + public void testTimedAwait_Interruptible() { + final int initialCount = ThreadLocalRandom.current().nextInt(1, 3); + final CountDownLatch l = new CountDownLatch(initialCount); + final CountDownLatch pleaseInterrupt = new CountDownLatch(1); + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + Thread.currentThread().interrupt(); + try { + l.await(randomTimeout(), randomTimeUnit()); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + pleaseInterrupt.countDown(); + try { + l.await(LONGER_DELAY_MS, MILLISECONDS); + shouldThrow(); + } catch (InterruptedException success) {} + assertFalse(Thread.interrupted()); + + assertEquals(initialCount, l.getCount()); + }}); + + await(pleaseInterrupt); + if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING); + t.interrupt(); + awaitTermination(t); } /** * timed await times out if not counted down before timeout */ - public void testAwaitTimeout() { + public void testAwaitTimeout() throws InterruptedException { final CountDownLatch l = new CountDownLatch(1); - Thread t = new Thread(new Runnable() { - public void run() { - try { - threadAssertTrue(l.getCount() > 0); - threadAssertFalse(l.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS)); - threadAssertTrue(l.getCount() > 0); - } catch(InterruptedException ie){ - threadUnexpectedException(); - } - } - }); - t.start(); - try { - assertEquals(l.getCount(), 1); - t.join(); - } catch (InterruptedException e){ - unexpectedException(); - } + Thread t = newStartedThread(new CheckedRunnable() { + public void realRun() throws InterruptedException { + assertEquals(1, l.getCount()); + + long startTime = System.nanoTime(); + assertFalse(l.await(timeoutMillis(), MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis()); + + assertEquals(1, l.getCount()); + }}); + + awaitTermination(t); + assertEquals(1, l.getCount()); + } + + /** + * toString indicates current count + */ + public void testToString() { + CountDownLatch s = new CountDownLatch(2); + assertTrue(s.toString().contains("Count = 2")); + s.countDown(); + assertTrue(s.toString().contains("Count = 1")); + s.countDown(); + assertTrue(s.toString().contains("Count = 0")); } }