Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/test/java/util/concurrent/Phaser/Basic.java
+++ new/test/java/util/concurrent/Phaser/Basic.java
1 1 /*
2 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 3 *
4 4 * This code is free software; you can redistribute it and/or modify it
5 5 * under the terms of the GNU General Public License version 2 only, as
6 6 * published by the Free Software Foundation.
7 7 *
8 8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 11 * version 2 for more details (a copy is included in the LICENSE file that
12 12 * accompanied this code).
13 13 *
14 14 * You should have received a copy of the GNU General Public License version
15 15 * 2 along with this work; if not, write to the Free Software Foundation,
16 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 17 *
18 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 19 * or visit www.oracle.com if you need additional information or have any
20 20 * questions.
21 21 */
22 22
23 23 /*
24 24 * This file is available under and governed by the GNU General Public
25 25 * License version 2 only, as published by the Free Software Foundation.
26 26 * However, the following notice accompanied the original version of this
27 27 * file:
28 28 *
29 29 * Written by Doug Lea with assistance from members of JCP JSR-166
30 30 * Expert Group and released to the public domain, as explained at
31 31 * http://creativecommons.org/licenses/publicdomain
32 32 */
33 33
34 34 /*
35 35 * @test
36 36 * @bug 6445158
37 37 * @summary Basic tests for Phaser
38 38 * @author Chris Hegarty
39 39 */
40 40
41 41 import java.util.Iterator;
42 42 import java.util.LinkedList;
43 43 import java.util.concurrent.Phaser;
44 44 import java.util.concurrent.TimeUnit;
↓ open down ↓ |
44 lines elided |
↑ open up ↑ |
45 45 import java.util.concurrent.TimeoutException;
46 46 import java.util.concurrent.atomic.AtomicInteger;
47 47 import static java.util.concurrent.TimeUnit.*;
48 48
49 49 public class Basic {
50 50
51 51 private static void checkTerminated(final Phaser phaser) {
52 52 check(phaser.isTerminated());
53 53 int unarriverParties = phaser.getUnarrivedParties();
54 54 int registeredParties = phaser.getRegisteredParties();
55 - equal(phaser.arrive(), -1);
56 - equal(phaser.arriveAndDeregister(), -1);
57 - equal(phaser.arriveAndAwaitAdvance(), -1);
58 - equal(phaser.bulkRegister(10), -1);
59 - equal(phaser.getPhase(), -1);
60 - equal(phaser.register(), -1);
55 + int phase = phaser.getPhase();
56 + check(phase < 0);
57 + equal(phase, phaser.arrive());
58 + equal(phase, phaser.arriveAndDeregister());
59 + equal(phase, phaser.arriveAndAwaitAdvance());
60 + equal(phase, phaser.bulkRegister(10));
61 + equal(phase, phaser.register());
61 62 try {
62 - equal(phaser.awaitAdvanceInterruptibly(0), -1);
63 - equal(phaser.awaitAdvanceInterruptibly(0, 10, SECONDS), -1);
63 + equal(phase, phaser.awaitAdvanceInterruptibly(0));
64 + equal(phase, phaser.awaitAdvanceInterruptibly(0, 10, SECONDS));
64 65 } catch (Exception ie) {
65 66 unexpected(ie);
66 67 }
67 68 equal(phaser.getUnarrivedParties(), unarriverParties);
68 69 equal(phaser.getRegisteredParties(), registeredParties);
69 70 }
70 71
71 72 private static void checkResult(Arriver a, Class<? extends Throwable> c) {
72 73 Throwable t = a.result();
73 74 if (! ((t == null && c == null) || (c != null && c.isInstance(t)))) {
74 75 // t.printStackTrace();
75 76 fail("Mismatch in thread " +
76 77 a.getName() + ": " +
77 78 t + ", " +
78 79 (c == null ? "<null>" : c.getName()));
79 80 } else {
80 81 pass();
81 82 }
82 83 }
83 84
84 85 //----------------------------------------------------------------
85 86 // Mechanism to get all test threads into "running" mode.
86 87 //----------------------------------------------------------------
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
87 88 private static Phaser atTheStartingGate = new Phaser(3);
88 89
89 90 private static void toTheStartingGate() {
90 91 try {
91 92 boolean expectNextPhase = false;
92 93 if (atTheStartingGate.getUnarrivedParties() == 1) {
93 94 expectNextPhase = true;
94 95 }
95 96 int phase = atTheStartingGate.getPhase();
96 97 equal(phase, atTheStartingGate.arrive());
97 - int AwaitPhase = atTheStartingGate.awaitAdvanceInterruptibly(phase,
98 - 10,
99 - SECONDS);
100 - if (expectNextPhase) check(AwaitPhase == (phase + 1));
98 + int awaitPhase = atTheStartingGate.awaitAdvanceInterruptibly
99 + (phase, 10, SECONDS);
100 + if (expectNextPhase) check(awaitPhase == (phase + 1));
101 101
102 102 pass();
103 103 } catch (Throwable t) {
104 104 unexpected(t);
105 105 // reset(atTheStartingGate);
106 106 throw new Error(t);
107 107 }
108 108 }
109 109
110 110 //----------------------------------------------------------------
111 111 // Convenience methods for creating threads that call arrive,
112 112 // awaitAdvance, arriveAndAwaitAdvance, awaitAdvanceInterruptibly
113 113 //----------------------------------------------------------------
114 114 private static abstract class Arriver extends Thread {
115 115 static AtomicInteger count = new AtomicInteger(1);
116 116
117 117 Arriver() {
118 118 this("Arriver");
119 119 }
120 120
121 121 Arriver(String name) {
122 122 this.setName(name + ":" + count.getAndIncrement());
123 123 this.setDaemon(true);
124 124 }
125 125
126 126 private volatile Throwable result;
127 127 private volatile int phase;
128 128 protected void result(Throwable result) { this.result = result; }
129 129 public Throwable result() { return this.result; }
130 130 protected void phase(int phase) { this.phase = phase; }
131 131 public int phase() { return this.phase; }
132 132 }
133 133
134 134 private static abstract class Awaiter extends Arriver {
135 135 Awaiter() { super("Awaiter"); }
136 136 Awaiter(String name) { super(name); }
137 137 }
138 138
139 139 private static Arriver arriver(final Phaser phaser) {
140 140 return new Arriver() { public void run() {
141 141 toTheStartingGate();
142 142
143 143 try { phase(phaser.arrive()); }
144 144 catch (Throwable result) { result(result); }}};
145 145 }
146 146
147 147 private static AtomicInteger cycleArriveAwaitAdvance = new AtomicInteger(1);
148 148
149 149 private static Awaiter awaiter(final Phaser phaser) {
150 150 return new Awaiter() { public void run() {
151 151 toTheStartingGate();
152 152
153 153 try {
154 154 if (cycleArriveAwaitAdvance.getAndIncrement() % 2 == 0)
155 155 phase(phaser.awaitAdvance(phaser.arrive()));
156 156 else
157 157 phase(phaser.arriveAndAwaitAdvance());
158 158 } catch (Throwable result) { result(result); }}};
159 159 }
160 160
161 161 private static Awaiter awaiter(final Phaser phaser,
162 162 final long timeout,
163 163 final TimeUnit unit) {
164 164 return new Awaiter("InterruptibleWaiter") { public void run() {
165 165 toTheStartingGate();
166 166
167 167 try {
168 168 if (timeout < 0)
169 169 phase(phaser.awaitAdvanceInterruptibly(phaser.arrive()));
170 170 else
171 171 phase(phaser.awaitAdvanceInterruptibly(phaser.arrive(),
172 172 timeout,
173 173 unit));
174 174 } catch (Throwable result) { result(result); }}};
175 175 }
176 176
177 177 // Returns an infinite lazy list of all possible arriver/awaiter combinations.
178 178 private static Iterator<Arriver> arriverIterator(final Phaser phaser) {
179 179 return new Iterator<Arriver>() {
180 180 int i = 0;
181 181 public boolean hasNext() { return true; }
182 182 public Arriver next() {
183 183 switch ((i++)&7) {
184 184 case 0: case 4:
185 185 return arriver(phaser);
186 186 case 1: case 5:
187 187 return awaiter(phaser);
188 188 case 2: case 6: case 7:
189 189 return awaiter(phaser, -1, SECONDS);
190 190 default:
191 191 return awaiter(phaser, 10, SECONDS); }}
192 192 public void remove() {throw new UnsupportedOperationException();}};
193 193 }
194 194
195 195 // Returns an infinite lazy list of all possible awaiter only combinations.
196 196 private static Iterator<Awaiter> awaiterIterator(final Phaser phaser) {
197 197 return new Iterator<Awaiter>() {
198 198 int i = 0;
199 199 public boolean hasNext() { return true; }
200 200 public Awaiter next() {
201 201 switch ((i++)&7) {
202 202 case 1: case 4: case 7:
203 203 return awaiter(phaser);
204 204 case 2: case 5:
205 205 return awaiter(phaser, -1, SECONDS);
206 206 default:
207 207 return awaiter(phaser, 10, SECONDS); }}
208 208 public void remove() {throw new UnsupportedOperationException();}};
209 209 }
210 210
211 211 private static void realMain(String[] args) throws Throwable {
212 212
213 213 Thread.currentThread().setName("mainThread");
214 214
215 215 //----------------------------------------------------------------
216 216 // Normal use
217 217 //----------------------------------------------------------------
218 218 try {
219 219 Phaser phaser = new Phaser(3);
220 220 equal(phaser.getRegisteredParties(), 3);
221 221 equal(phaser.getArrivedParties(), 0);
222 222 equal(phaser.getPhase(), 0);
223 223 check(phaser.getRoot().equals(phaser));
224 224 equal(phaser.getParent(), null);
225 225 check(!phaser.isTerminated());
226 226
227 227 Iterator<Arriver> arrivers = arriverIterator(phaser);
228 228 int phase = 0;
229 229 for (int i = 0; i < 10; i++) {
230 230 equal(phaser.getPhase(), phase++);
231 231 Arriver a1 = arrivers.next(); a1.start();
232 232 Arriver a2 = arrivers.next(); a2.start();
233 233 toTheStartingGate();
234 234 phaser.arriveAndAwaitAdvance();
235 235 a1.join();
236 236 a2.join();
237 237 checkResult(a1, null);
238 238 checkResult(a2, null);
239 239 check(!phaser.isTerminated());
240 240 equal(phaser.getRegisteredParties(), 3);
241 241 equal(phaser.getArrivedParties(), 0);
242 242 }
243 243 } catch (Throwable t) { unexpected(t); }
244 244
245 245 //----------------------------------------------------------------
246 246 // One thread interrupted
247 247 //----------------------------------------------------------------
248 248 try {
249 249 Phaser phaser = new Phaser(3);
250 250 Iterator<Arriver> arrivers = arriverIterator(phaser);
251 251 int phase = phaser.getPhase();
252 252 for (int i = 0; i < 4; i++) {
253 253 check(phaser.getPhase() == phase);
254 254 Awaiter a1 = awaiter(phaser, 10, SECONDS); a1.start();
255 255 Arriver a2 = arrivers.next(); a2.start();
256 256 toTheStartingGate();
257 257 a1.interrupt();
258 258 a1.join();
259 259 phaser.arriveAndAwaitAdvance();
260 260 a2.join();
261 261 checkResult(a1, InterruptedException.class);
262 262 checkResult(a2, null);
263 263 check(!phaser.isTerminated());
↓ open down ↓ |
153 lines elided |
↑ open up ↑ |
264 264 equal(phaser.getRegisteredParties(), 3);
265 265 equal(phaser.getArrivedParties(), 0);
266 266 phase++;
267 267 }
268 268 } catch (Throwable t) { unexpected(t); }
269 269
270 270 //----------------------------------------------------------------
271 271 // Phaser is terminated while threads are waiting
272 272 //----------------------------------------------------------------
273 273 try {
274 - Phaser phaser = new Phaser(3);
275 - Iterator<Awaiter> awaiters = awaiterIterator(phaser);
276 274 for (int i = 0; i < 4; i++) {
275 + Phaser phaser = new Phaser(3);
276 + Iterator<Awaiter> awaiters = awaiterIterator(phaser);
277 277 Arriver a1 = awaiters.next(); a1.start();
278 278 Arriver a2 = awaiters.next(); a2.start();
279 279 toTheStartingGate();
280 280 while (phaser.getArrivedParties() < 2) Thread.yield();
281 + equal(0, phaser.getPhase());
281 282 phaser.forceTermination();
282 283 a1.join();
283 284 a2.join();
284 - check(a1.phase == -1);
285 - check(a2.phase == -1);
285 + equal(0 + Integer.MIN_VALUE, a1.phase);
286 + equal(0 + Integer.MIN_VALUE, a2.phase);
286 287 int arrivedParties = phaser.getArrivedParties();
287 288 checkTerminated(phaser);
288 289 equal(phaser.getArrivedParties(), arrivedParties);
289 290 }
290 291 } catch (Throwable t) { unexpected(t); }
291 292
292 293 //----------------------------------------------------------------
293 294 // Adds new unarrived parties to this phaser
294 295 //----------------------------------------------------------------
295 296 try {
296 297 Phaser phaser = new Phaser(1);
297 298 Iterator<Arriver> arrivers = arriverIterator(phaser);
298 299 LinkedList<Arriver> arriverList = new LinkedList<Arriver>();
299 300 int phase = phaser.getPhase();
300 301 for (int i = 1; i < 5; i++) {
301 302 atTheStartingGate = new Phaser(1+(3*i));
302 303 check(phaser.getPhase() == phase);
303 304 // register 3 more
304 305 phaser.register(); phaser.register(); phaser.register();
305 306 for (int z=0; z<(3*i); z++) {
306 307 arriverList.add(arrivers.next());
307 308 }
308 309 for (Arriver arriver : arriverList)
309 310 arriver.start();
310 311
311 312 toTheStartingGate();
312 313 phaser.arriveAndAwaitAdvance();
313 314
314 315 for (Arriver arriver : arriverList) {
315 316 arriver.join();
316 317 checkResult(arriver, null);
317 318 }
318 319 equal(phaser.getRegisteredParties(), 1 + (3*i));
319 320 equal(phaser.getArrivedParties(), 0);
320 321 arriverList.clear();
321 322 phase++;
322 323 }
323 324 atTheStartingGate = new Phaser(3);
324 325 } catch (Throwable t) { unexpected(t); }
325 326
326 327 //----------------------------------------------------------------
327 328 // One thread timed out
328 329 //----------------------------------------------------------------
329 330 try {
330 331 Phaser phaser = new Phaser(3);
331 332 Iterator<Arriver> arrivers = arriverIterator(phaser);
332 333 for (long timeout : new long[] { 0L, 5L }) {
333 334 for (int i = 0; i < 2; i++) {
334 335 Awaiter a1 = awaiter(phaser, timeout, SECONDS); a1.start();
335 336 Arriver a2 = arrivers.next(); a2.start();
336 337 toTheStartingGate();
337 338 a1.join();
338 339 checkResult(a1, TimeoutException.class);
339 340 phaser.arrive();
340 341 a2.join();
341 342 checkResult(a2, null);
342 343 check(!phaser.isTerminated());
343 344 }
344 345 }
345 346 } catch (Throwable t) { unexpected(t); }
346 347
347 348 //----------------------------------------------------------------
348 349 // Barrier action completed normally
349 350 //----------------------------------------------------------------
350 351 try {
351 352 final AtomicInteger count = new AtomicInteger(0);
352 353 final Phaser[] kludge = new Phaser[1];
353 354 Phaser phaser = new Phaser(3) {
354 355 @Override
355 356 protected boolean onAdvance(int phase, int registeredParties) {
356 357 int countPhase = count.getAndIncrement();
357 358 equal(countPhase, phase);
358 359 equal(kludge[0].getPhase(), phase);
359 360 equal(kludge[0].getRegisteredParties(), registeredParties);
360 361 if (phase >= 3)
361 362 return true; // terminate
362 363
363 364 return false;
364 365 }
365 366 };
366 367 kludge[0] = phaser;
367 368 equal(phaser.getRegisteredParties(), 3);
368 369 Iterator<Awaiter> awaiters = awaiterIterator(phaser);
369 370 for (int i = 0; i < 4; i++) {
370 371 Awaiter a1 = awaiters.next(); a1.start();
371 372 Awaiter a2 = awaiters.next(); a2.start();
372 373 toTheStartingGate();
373 374 while (phaser.getArrivedParties() < 2) Thread.yield();
374 375 phaser.arrive();
375 376 a1.join();
376 377 a2.join();
377 378 checkResult(a1, null);
378 379 checkResult(a2, null);
379 380 equal(count.get(), i+1);
380 381 if (i < 3) {
381 382 check(!phaser.isTerminated());
382 383 equal(phaser.getRegisteredParties(), 3);
383 384 equal(phaser.getArrivedParties(), 0);
384 385 equal(phaser.getUnarrivedParties(), 3);
385 386 equal(phaser.getPhase(), count.get());
386 387 } else
387 388 checkTerminated(phaser);
388 389 }
389 390 } catch (Throwable t) { unexpected(t); }
390 391
391 392 }
392 393
393 394 //--------------------- Infrastructure ---------------------------
394 395 static volatile int passed = 0, failed = 0;
395 396 static void pass() {passed++;}
396 397 static void fail() {failed++; Thread.dumpStack();}
397 398 static void fail(String msg) {System.out.println(msg); fail();}
398 399 static void unexpected(Throwable t) {failed++; t.printStackTrace();}
399 400 static void check(boolean cond) {if (cond) pass(); else fail();}
400 401 static void equal(Object x, Object y) {
401 402 if (x == null ? y == null : x.equals(y)) pass();
402 403 else fail(x + " not equal to " + y);}
403 404 public static void main(String[] args) throws Throwable {
404 405 try {realMain(args);} catch (Throwable t) {unexpected(t);}
405 406 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
406 407 if (failed > 0) throw new AssertionError("Some tests failed");}
407 408 }
↓ open down ↓ |
112 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX