1/*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9package jsr166;
10
11import junit.framework.*;
12import java.util.*;
13import java.util.concurrent.CountDownLatch;
14import static java.util.concurrent.TimeUnit.MILLISECONDS;
15
16public class CountDownLatchTest extends JSR166TestCase {
17
18    /**
19     * negative constructor argument throws IAE
20     */
21    public void testConstructor() {
22        try {
23            new CountDownLatch(-1);
24            shouldThrow();
25        } catch (IllegalArgumentException success) {}
26    }
27
28    /**
29     * getCount returns initial count and decreases after countDown
30     */
31    public void testGetCount() {
32        final CountDownLatch l = new CountDownLatch(2);
33        assertEquals(2, l.getCount());
34        l.countDown();
35        assertEquals(1, l.getCount());
36    }
37
38    /**
39     * countDown decrements count when positive and has no effect when zero
40     */
41    public void testCountDown() {
42        final CountDownLatch l = new CountDownLatch(1);
43        assertEquals(1, l.getCount());
44        l.countDown();
45        assertEquals(0, l.getCount());
46        l.countDown();
47        assertEquals(0, l.getCount());
48    }
49
50    /**
51     * await returns after countDown to zero, but not before
52     */
53    public void testAwait() {
54        final CountDownLatch l = new CountDownLatch(2);
55        final CountDownLatch pleaseCountDown = new CountDownLatch(1);
56
57        Thread t = newStartedThread(new CheckedRunnable() {
58            public void realRun() throws InterruptedException {
59                assertEquals(2, l.getCount());
60                pleaseCountDown.countDown();
61                l.await();
62                assertEquals(0, l.getCount());
63            }});
64
65        await(pleaseCountDown);
66        assertEquals(2, l.getCount());
67        l.countDown();
68        assertEquals(1, l.getCount());
69        assertThreadStaysAlive(t);
70        l.countDown();
71        assertEquals(0, l.getCount());
72        awaitTermination(t);
73    }
74
75    /**
76     * timed await returns after countDown to zero
77     */
78    public void testTimedAwait() {
79        final CountDownLatch l = new CountDownLatch(2);
80        final CountDownLatch pleaseCountDown = new CountDownLatch(1);
81
82        Thread t = newStartedThread(new CheckedRunnable() {
83            public void realRun() throws InterruptedException {
84                assertEquals(2, l.getCount());
85                pleaseCountDown.countDown();
86                assertTrue(l.await(LONG_DELAY_MS, MILLISECONDS));
87                assertEquals(0, l.getCount());
88            }});
89
90        await(pleaseCountDown);
91        assertEquals(2, l.getCount());
92        l.countDown();
93        assertEquals(1, l.getCount());
94        assertThreadStaysAlive(t);
95        l.countDown();
96        assertEquals(0, l.getCount());
97        awaitTermination(t);
98    }
99
100    /**
101     * await throws IE if interrupted before counted down
102     */
103    public void testAwait_Interruptible() {
104        final CountDownLatch l = new CountDownLatch(1);
105        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
106        Thread t = newStartedThread(new CheckedRunnable() {
107            public void realRun() throws InterruptedException {
108                Thread.currentThread().interrupt();
109                try {
110                    l.await();
111                    shouldThrow();
112                } catch (InterruptedException success) {}
113                assertFalse(Thread.interrupted());
114
115                pleaseInterrupt.countDown();
116                try {
117                    l.await();
118                    shouldThrow();
119                } catch (InterruptedException success) {}
120                assertFalse(Thread.interrupted());
121
122                assertEquals(1, l.getCount());
123            }});
124
125        await(pleaseInterrupt);
126        assertThreadStaysAlive(t);
127        t.interrupt();
128        awaitTermination(t);
129    }
130
131    /**
132     * timed await throws IE if interrupted before counted down
133     */
134    public void testTimedAwait_Interruptible() {
135        final CountDownLatch l = new CountDownLatch(1);
136        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
137        Thread t = newStartedThread(new CheckedRunnable() {
138            public void realRun() throws InterruptedException {
139                Thread.currentThread().interrupt();
140                try {
141                    l.await(LONG_DELAY_MS, MILLISECONDS);
142                    shouldThrow();
143                } catch (InterruptedException success) {}
144                assertFalse(Thread.interrupted());
145
146                pleaseInterrupt.countDown();
147                try {
148                    l.await(LONG_DELAY_MS, MILLISECONDS);
149                    shouldThrow();
150                } catch (InterruptedException success) {}
151                assertFalse(Thread.interrupted());
152
153                assertEquals(1, l.getCount());
154            }});
155
156        await(pleaseInterrupt);
157        assertThreadStaysAlive(t);
158        t.interrupt();
159        awaitTermination(t);
160    }
161
162    /**
163     * timed await times out if not counted down before timeout
164     */
165    public void testAwaitTimeout() throws InterruptedException {
166        final CountDownLatch l = new CountDownLatch(1);
167        Thread t = newStartedThread(new CheckedRunnable() {
168            public void realRun() throws InterruptedException {
169                assertEquals(1, l.getCount());
170                assertFalse(l.await(timeoutMillis(), MILLISECONDS));
171                assertEquals(1, l.getCount());
172            }});
173
174        awaitTermination(t);
175        assertEquals(1, l.getCount());
176    }
177
178    /**
179     * toString indicates current count
180     */
181    public void testToString() {
182        CountDownLatch s = new CountDownLatch(2);
183        assertTrue(s.toString().contains("Count = 2"));
184        s.countDown();
185        assertTrue(s.toString().contains("Count = 1"));
186        s.countDown();
187        assertTrue(s.toString().contains("Count = 0"));
188    }
189
190}
191