1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.
7  *
8  * This code is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * version 2 for more details (a copy is included in the LICENSE file that
12  * accompanied this code).
13  *
14  * You should have received a copy of the GNU General Public License version
15  * 2 along with this work; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19  * or visit www.oracle.com if you need additional information or have any
20  * questions.
21  */
22 
23 /*
24  * This file is available under and governed by the GNU General Public
25  * License version 2 only, as published by the Free Software Foundation.
26  * However, the following notice accompanied the original version of this
27  * file:
28  *
29  * Written by Doug Lea with assistance from members of JCP JSR-166
30  * Expert Group and released to the public domain, as explained at
31  * http://creativecommons.org/publicdomain/zero/1.0/
32  * Other contributors include Andrew Wright, Jeffrey Hayes,
33  * Pat Fisher, Mike Judd.
34  */
35 
36 import static java.util.concurrent.TimeUnit.MILLISECONDS;
37 
38 import java.util.concurrent.CountDownLatch;
39 import java.util.concurrent.ThreadLocalRandom;
40 
41 import junit.framework.Test;
42 import junit.framework.TestSuite;
43 
44 public class CountDownLatchTest extends JSR166TestCase {
45     public static void main(String[] args) {
46         main(suite(), args);
main(String[] args)47     }
48     public static Test suite() {
49         return new TestSuite(CountDownLatchTest.class);
50     }
51 
klazz()52     /**
53      * negative constructor argument throws IllegalArgumentException
54      */
55     public void testConstructor() {
56         try {
57             new CountDownLatch(-1);
58             shouldThrow();
59         } catch (IllegalArgumentException success) {}
60     }
61 
62     /**
populatedSet(int n)63      * getCount returns initial count and decreases after countDown
64      */
65     public void testGetCount() {
66         final CountDownLatch l = new CountDownLatch(2);
67         assertEquals(2, l.getCount());
68         l.countDown();
69         assertEquals(1, l.getCount());
70     }
71 
72     /**
populatedSet(Integer[] elements)73      * countDown decrements count when positive and has no effect when zero
74      */
75     public void testCountDown() {
76         final CountDownLatch l = new CountDownLatch(1);
77         assertEquals(1, l.getCount());
78         l.countDown();
79         assertEquals(0, l.getCount());
80         l.countDown();
81         assertEquals(0, l.getCount());
82     }
83 
84     /**
85      * await returns after countDown to zero, but not before
testConstructor()86      */
87     public void testAwait() {
88         final CountDownLatch l = new CountDownLatch(2);
89         final CountDownLatch pleaseCountDown = new CountDownLatch(1);
90 
91         Thread t = newStartedThread(new CheckedRunnable() {
92             public void realRun() throws InterruptedException {
93                 assertEquals(2, l.getCount());
94                 pleaseCountDown.countDown();
95                 l.await();
96                 assertEquals(0, l.getCount());
97             }});
98 
99         await(pleaseCountDown);
100         assertEquals(2, l.getCount());
101         l.countDown();
102         assertEquals(1, l.getCount());
103         if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING);
104         l.countDown();
105         assertEquals(0, l.getCount());
106         awaitTermination(t);
107     }
108 
109     /**
110      * timed await returns after countDown to zero
111      */
112     public void testTimedAwait() {
113         final CountDownLatch l = new CountDownLatch(2);
114         final CountDownLatch pleaseCountDown = new CountDownLatch(1);
115 
116         Thread t = newStartedThread(new CheckedRunnable() {
testAddAll2()117             public void realRun() throws InterruptedException {
118                 assertEquals(2, l.getCount());
119                 pleaseCountDown.countDown();
120                 assertTrue(l.await(LONG_DELAY_MS, MILLISECONDS));
121                 assertEquals(0, l.getCount());
122             }});
123 
124         await(pleaseCountDown);
125         assertEquals(2, l.getCount());
126         l.countDown();
127         assertEquals(1, l.getCount());
128         if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING);
testAdd2()129         l.countDown();
130         assertEquals(0, l.getCount());
131         awaitTermination(t);
132     }
133 
134     /**
135      * await throws InterruptedException if interrupted before counted down
136      */
137     public void testAwait_Interruptible() {
testAdd3()138         final CountDownLatch l = new CountDownLatch(1);
139         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
140         Thread t = newStartedThread(new CheckedRunnable() {
141             public void realRun() throws InterruptedException {
142                 Thread.currentThread().interrupt();
143                 try {
144                     l.await();
145                     shouldThrow();
146                 } catch (InterruptedException success) {}
testClear()147                 assertFalse(Thread.interrupted());
148 
149                 pleaseInterrupt.countDown();
150                 try {
151                     l.await();
152                     shouldThrow();
153                 } catch (InterruptedException success) {}
154                 assertFalse(Thread.interrupted());
155 
156                 assertEquals(1, l.getCount());
testContains()157             }});
158 
159         await(pleaseInterrupt);
160         if (randomBoolean()) assertThreadBlocks(t, Thread.State.WAITING);
161         t.interrupt();
162         awaitTermination(t);
163     }
164 
165     /**
testEquals()166      * timed await throws InterruptedException if interrupted before counted down
167      */
168     public void testTimedAwait_Interruptible() {
169         final int initialCount = ThreadLocalRandom.current().nextInt(1, 3);
170         final CountDownLatch l = new CountDownLatch(initialCount);
171         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
172         Thread t = newStartedThread(new CheckedRunnable() {
173             public void realRun() throws InterruptedException {
174                 Thread.currentThread().interrupt();
175                 try {
176                     l.await(randomTimeout(), randomTimeUnit());
177                     shouldThrow();
178                 } catch (InterruptedException success) {}
179                 assertFalse(Thread.interrupted());
180 
181                 pleaseInterrupt.countDown();
182                 try {
183                     l.await(LONGER_DELAY_MS, MILLISECONDS);
184                     shouldThrow();
185                 } catch (InterruptedException success) {}
186                 assertFalse(Thread.interrupted());
187 
188                 assertEquals(initialCount, l.getCount());
189             }});
190 
191         await(pleaseInterrupt);
192         if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING);
193         t.interrupt();
194         awaitTermination(t);
195     }
196 
197     /**
198      * timed await times out if not counted down before timeout
199      */
200     public void testAwaitTimeout() throws InterruptedException {
201         final CountDownLatch l = new CountDownLatch(1);
202         Thread t = newStartedThread(new CheckedRunnable() {
203             public void realRun() throws InterruptedException {
204                 assertEquals(1, l.getCount());
205 
206                 long startTime = System.nanoTime();
207                 assertFalse(l.await(timeoutMillis(), MILLISECONDS));
208                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
209 
210                 assertEquals(1, l.getCount());
211             }});
212 
213         awaitTermination(t);
214         assertEquals(1, l.getCount());
215     }
testContainsAll()216 
217     /**
218      * toString indicates current count
219      */
220     public void testToString() {
221         CountDownLatch s = new CountDownLatch(2);
222         assertTrue(s.toString().contains("Count = 2"));
223         s.countDown();
224         assertTrue(s.toString().contains("Count = 1"));
225         s.countDown();
226         assertTrue(s.toString().contains("Count = 0"));
227     }
228 
229 }
230