blob: 9e52937056ca905b47f1c552744f4f5bebdfdf94 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 * @test
26 * @bug 6332435
27 * @summary Basic tests for CountDownLatch
28 * @author Seetharam Avadhanam, Martin Buchholz
29 */
30
31import java.util.concurrent.*;
32import java.util.concurrent.atomic.AtomicInteger;
33
34interface AwaiterFactory {
35 Awaiter getAwaiter();
36}
37
38abstract class Awaiter extends Thread {
39 private volatile Throwable result = null;
40 protected void result(Throwable result) { this.result = result; }
41 public Throwable result() { return this.result; }
42}
43
44public class Basic {
45
46 private void toTheStartingGate(CountDownLatch gate) {
47 try {
48 gate.await();
49 }
50 catch (Throwable t) { fail(t); }
51 }
52
53 private Awaiter awaiter(final CountDownLatch latch,
54 final CountDownLatch gate) {
55 return new Awaiter() { public void run() {
56 System.out.println("without millis: " + latch.toString());
57 gate.countDown();
58
59 try {
60 latch.await();
61 System.out.println("without millis - ComingOut");
62 }
63 catch (Throwable result) { result(result); }}};
64 }
65
66 private Awaiter awaiter(final CountDownLatch latch,
67 final CountDownLatch gate,
68 final long millis) {
69 return new Awaiter() { public void run() {
70 System.out.println("with millis: "+latch.toString());
71 gate.countDown();
72
73 try {
74 latch.await(millis, TimeUnit.MILLISECONDS);
75 System.out.println("with millis - ComingOut");
76 }
77 catch (Throwable result) { result(result); }}};
78 }
79
80 private AwaiterFactory awaiterFactories(final CountDownLatch latch,
81 final CountDownLatch gate,
82 final int i) {
83 if (i == 1)
84 return new AwaiterFactory() { public Awaiter getAwaiter() {
85 return awaiter(latch, gate); }};
86
87 return new AwaiterFactory() { public Awaiter getAwaiter() {
88 return awaiter(latch, gate, 10000); }};
89 }
90
91 //----------------------------------------------------------------
92 // Normal use
93 //----------------------------------------------------------------
94 public static void normalUse() throws Throwable {
95 int count = 0;
96 Basic test = new Basic();
97 CountDownLatch latch = new CountDownLatch(3);
98 Awaiter a[] = new Awaiter[12];
99
100 for (int i = 0; i < 3; i++) {
101 CountDownLatch gate = new CountDownLatch(4);
102 AwaiterFactory factory1 = test.awaiterFactories(latch, gate, 1);
103 AwaiterFactory factory2 = test.awaiterFactories(latch, gate, 0);
104 a[count] = factory1.getAwaiter(); a[count++].start();
105 a[count] = factory1.getAwaiter(); a[count++].start();
106 a[count] = factory2.getAwaiter(); a[count++].start();
107 a[count] = factory2.getAwaiter(); a[count++].start();
108 test.toTheStartingGate(gate);
109 System.out.println("Main Thread: " + latch.toString());
110 latch.countDown();
111 checkCount(latch, 2-i);
112 }
113 for (int i = 0; i < 12; i++)
114 a[i].join();
115
116 for (int i = 0; i < 12; i++)
117 checkResult(a[i], null);
118 }
119
120 //----------------------------------------------------------------
121 // One thread interrupted
122 //----------------------------------------------------------------
123 public static void threadInterrupted() throws Throwable{
124 int count = 0;
125 Basic test = new Basic();
126 CountDownLatch latch = new CountDownLatch(3);
127 Awaiter a[] = new Awaiter[12];
128
129 for (int i = 0; i < 3; i++) {
130 CountDownLatch gate = new CountDownLatch(4);
131 AwaiterFactory factory1 = test.awaiterFactories(latch, gate, 1);
132 AwaiterFactory factory2 = test.awaiterFactories(latch, gate, 0);
133 a[count] = factory1.getAwaiter(); a[count++].start();
134 a[count] = factory1.getAwaiter(); a[count++].start();
135 a[count] = factory2.getAwaiter(); a[count++].start();
136 a[count] = factory2.getAwaiter(); a[count++].start();
137 a[count-1].interrupt();
138 test.toTheStartingGate(gate);
139 System.out.println("Main Thread: " + latch.toString());
140 latch.countDown();
141 checkCount(latch, 2-i);
142 }
143 for (int i = 0; i < 12; i++)
144 a[i].join();
145
146 for (int i = 0; i < 12; i++)
147 checkResult(a[i],
148 (i % 4) == 3 ? InterruptedException.class : null);
149 }
150
151 //----------------------------------------------------------------
152 // One thread timed out
153 //----------------------------------------------------------------
154 public static void timeOut() throws Throwable {
155 int count =0;
156 Basic test = new Basic();
157 CountDownLatch latch = new CountDownLatch(3);
158 Awaiter a[] = new Awaiter[12];
159
160 long[] timeout = { 0L, 5L, 10L };
161
162 for (int i = 0; i < 3; i++) {
163 CountDownLatch gate = new CountDownLatch(4);
164 AwaiterFactory factory1 = test.awaiterFactories(latch, gate, 1);
165 AwaiterFactory factory2 = test.awaiterFactories(latch, gate, 0);
166 a[count] = test.awaiter(latch, gate, timeout[i]); a[count++].start();
167 a[count] = factory1.getAwaiter(); a[count++].start();
168 a[count] = factory2.getAwaiter(); a[count++].start();
169 a[count] = factory2.getAwaiter(); a[count++].start();
170 test.toTheStartingGate(gate);
171 System.out.println("Main Thread: " + latch.toString());
172 latch.countDown();
173 checkCount(latch, 2-i);
174 }
175 for (int i = 0; i < 12; i++)
176 a[i].join();
177
178 for (int i = 0; i < 12; i++)
179 checkResult(a[i], null);
180 }
181
182 public static void main(String[] args) throws Throwable {
183 normalUse();
184 threadInterrupted();
185 timeOut();
186 if (failures.get() > 0L)
187 throw new AssertionError(failures.get() + " failures");
188 }
189
190 private static final AtomicInteger failures = new AtomicInteger(0);
191
192 private static void fail(String msg) {
193 fail(new AssertionError(msg));
194 }
195
196 private static void fail(Throwable t) {
197 t.printStackTrace();
198 failures.getAndIncrement();
199 }
200
201 private static void checkCount(CountDownLatch b, int expected) {
202 if (b.getCount() != expected)
203 fail("Count = " + b.getCount() +
204 ", expected = " + expected);
205 }
206
207 private static void checkResult(Awaiter a, Class c) {
208 Throwable t = a.result();
209 if (! ((t == null && c == null) || c.isInstance(t))) {
210 System.out.println("Mismatch: " + t + ", " + c.getName());
211 failures.getAndIncrement();
212 }
213 }
214}