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 
40 import junit.framework.Test;
41 import junit.framework.TestSuite;
42 
43 public class CountDownLatchTest extends JSR166TestCase {
main(String[] args)44     public static void main(String[] args) {
45         main(suite(), args);
46     }
suite()47     public static Test suite() {
48         return new TestSuite(CountDownLatchTest.class);
49     }
50 
51     /**
52      * negative constructor argument throws IllegalArgumentException
53      */
testConstructor()54     public void testConstructor() {
55         try {
56             new CountDownLatch(-1);
57             shouldThrow();
58         } catch (IllegalArgumentException success) {}
59     }
60 
61     /**
62      * getCount returns initial count and decreases after countDown
63      */
testGetCount()64     public void testGetCount() {
65         final CountDownLatch l = new CountDownLatch(2);
66         assertEquals(2, l.getCount());
67         l.countDown();
68         assertEquals(1, l.getCount());
69     }
70 
71     /**
72      * countDown decrements count when positive and has no effect when zero
73      */
testCountDown()74     public void testCountDown() {
75         final CountDownLatch l = new CountDownLatch(1);
76         assertEquals(1, l.getCount());
77         l.countDown();
78         assertEquals(0, l.getCount());
79         l.countDown();
80         assertEquals(0, l.getCount());
81     }
82 
83     /**
84      * await returns after countDown to zero, but not before
85      */
testAwait()86     public void testAwait() {
87         final CountDownLatch l = new CountDownLatch(2);
88         final CountDownLatch pleaseCountDown = new CountDownLatch(1);
89 
90         Thread t = newStartedThread(new CheckedRunnable() {
91             public void realRun() throws InterruptedException {
92                 assertEquals(2, l.getCount());
93                 pleaseCountDown.countDown();
94                 l.await();
95                 assertEquals(0, l.getCount());
96             }});
97 
98         await(pleaseCountDown);
99         assertEquals(2, l.getCount());
100         l.countDown();
101         assertEquals(1, l.getCount());
102         assertThreadBlocks(t, Thread.State.WAITING);
103         l.countDown();
104         assertEquals(0, l.getCount());
105         awaitTermination(t);
106     }
107 
108     /**
109      * timed await returns after countDown to zero
110      */
testTimedAwait()111     public void testTimedAwait() {
112         final CountDownLatch l = new CountDownLatch(2);
113         final CountDownLatch pleaseCountDown = new CountDownLatch(1);
114 
115         Thread t = newStartedThread(new CheckedRunnable() {
116             public void realRun() throws InterruptedException {
117                 assertEquals(2, l.getCount());
118                 pleaseCountDown.countDown();
119                 assertTrue(l.await(LONG_DELAY_MS, MILLISECONDS));
120                 assertEquals(0, l.getCount());
121             }});
122 
123         await(pleaseCountDown);
124         assertEquals(2, l.getCount());
125         l.countDown();
126         assertEquals(1, l.getCount());
127         assertThreadBlocks(t, Thread.State.TIMED_WAITING);
128         l.countDown();
129         assertEquals(0, l.getCount());
130         awaitTermination(t);
131     }
132 
133     /**
134      * await throws InterruptedException if interrupted before counted down
135      */
testAwait_Interruptible()136     public void testAwait_Interruptible() {
137         final CountDownLatch l = new CountDownLatch(1);
138         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
139         Thread t = newStartedThread(new CheckedRunnable() {
140             public void realRun() throws InterruptedException {
141                 Thread.currentThread().interrupt();
142                 try {
143                     l.await();
144                     shouldThrow();
145                 } catch (InterruptedException success) {}
146                 assertFalse(Thread.interrupted());
147 
148                 pleaseInterrupt.countDown();
149                 try {
150                     l.await();
151                     shouldThrow();
152                 } catch (InterruptedException success) {}
153                 assertFalse(Thread.interrupted());
154 
155                 assertEquals(1, l.getCount());
156             }});
157 
158         await(pleaseInterrupt);
159         assertThreadBlocks(t, Thread.State.WAITING);
160         t.interrupt();
161         awaitTermination(t);
162     }
163 
164     /**
165      * timed await throws InterruptedException if interrupted before counted down
166      */
testTimedAwait_Interruptible()167     public void testTimedAwait_Interruptible() {
168         final CountDownLatch l = new CountDownLatch(1);
169         final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
170         Thread t = newStartedThread(new CheckedRunnable() {
171             public void realRun() throws InterruptedException {
172                 Thread.currentThread().interrupt();
173                 try {
174                     l.await(LONG_DELAY_MS, MILLISECONDS);
175                     shouldThrow();
176                 } catch (InterruptedException success) {}
177                 assertFalse(Thread.interrupted());
178 
179                 pleaseInterrupt.countDown();
180                 try {
181                     l.await(LONG_DELAY_MS, MILLISECONDS);
182                     shouldThrow();
183                 } catch (InterruptedException success) {}
184                 assertFalse(Thread.interrupted());
185 
186                 assertEquals(1, l.getCount());
187             }});
188 
189         await(pleaseInterrupt);
190         assertThreadBlocks(t, Thread.State.TIMED_WAITING);
191         t.interrupt();
192         awaitTermination(t);
193     }
194 
195     /**
196      * timed await times out if not counted down before timeout
197      */
testAwaitTimeout()198     public void testAwaitTimeout() throws InterruptedException {
199         final CountDownLatch l = new CountDownLatch(1);
200         Thread t = newStartedThread(new CheckedRunnable() {
201             public void realRun() throws InterruptedException {
202                 assertEquals(1, l.getCount());
203                 assertFalse(l.await(timeoutMillis(), MILLISECONDS));
204                 assertEquals(1, l.getCount());
205             }});
206 
207         awaitTermination(t);
208         assertEquals(1, l.getCount());
209     }
210 
211     /**
212      * toString indicates current count
213      */
testToString()214     public void testToString() {
215         CountDownLatch s = new CountDownLatch(2);
216         assertTrue(s.toString().contains("Count = 2"));
217         s.countDown();
218         assertTrue(s.toString().contains("Count = 1"));
219         s.countDown();
220         assertTrue(s.toString().contains("Count = 0"));
221     }
222 
223 }
224