32 * Expert Group and released to the public domain, as explained at |
32 * Expert Group and released to the public domain, as explained at |
33 * http://creativecommons.org/publicdomain/zero/1.0/ |
33 * http://creativecommons.org/publicdomain/zero/1.0/ |
34 */ |
34 */ |
35 |
35 |
36 package java.util.concurrent; |
36 package java.util.concurrent; |
37 import java.util.concurrent.locks.*; |
37 import java.util.concurrent.locks.Condition; |
|
38 import java.util.concurrent.locks.ReentrantLock; |
38 |
39 |
39 /** |
40 /** |
40 * A synchronization aid that allows a set of threads to all wait for |
41 * A synchronization aid that allows a set of threads to all wait for |
41 * each other to reach a common barrier point. CyclicBarriers are |
42 * each other to reach a common barrier point. CyclicBarriers are |
42 * useful in programs involving a fixed sized party of threads that |
43 * useful in programs involving a fixed sized party of threads that |
50 * This <em>barrier action</em> is useful |
51 * This <em>barrier action</em> is useful |
51 * for updating shared-state before any of the parties continue. |
52 * for updating shared-state before any of the parties continue. |
52 * |
53 * |
53 * <p><b>Sample usage:</b> Here is an example of |
54 * <p><b>Sample usage:</b> Here is an example of |
54 * using a barrier in a parallel decomposition design: |
55 * using a barrier in a parallel decomposition design: |
55 * <pre> |
56 * |
|
57 * <pre> {@code |
56 * class Solver { |
58 * class Solver { |
57 * final int N; |
59 * final int N; |
58 * final float[][] data; |
60 * final float[][] data; |
59 * final CyclicBarrier barrier; |
61 * final CyclicBarrier barrier; |
60 * |
62 * |
88 * for (int i = 0; i < N; ++i) |
90 * for (int i = 0; i < N; ++i) |
89 * new Thread(new Worker(i)).start(); |
91 * new Thread(new Worker(i)).start(); |
90 * |
92 * |
91 * waitUntilDone(); |
93 * waitUntilDone(); |
92 * } |
94 * } |
93 * } |
95 * }}</pre> |
94 * </pre> |
96 * |
95 * Here, each worker thread processes a row of the matrix then waits at the |
97 * Here, each worker thread processes a row of the matrix then waits at the |
96 * barrier until all rows have been processed. When all rows are processed |
98 * barrier until all rows have been processed. When all rows are processed |
97 * the supplied {@link Runnable} barrier action is executed and merges the |
99 * the supplied {@link Runnable} barrier action is executed and merges the |
98 * rows. If the merger |
100 * rows. If the merger |
99 * determines that a solution has been found then <tt>done()</tt> will return |
101 * determines that a solution has been found then <tt>done()</tt> will return |
103 * it is executed, then any of the threads in the party could execute that |
105 * it is executed, then any of the threads in the party could execute that |
104 * action when it is released. To facilitate this, each invocation of |
106 * action when it is released. To facilitate this, each invocation of |
105 * {@link #await} returns the arrival index of that thread at the barrier. |
107 * {@link #await} returns the arrival index of that thread at the barrier. |
106 * You can then choose which thread should execute the barrier action, for |
108 * You can then choose which thread should execute the barrier action, for |
107 * example: |
109 * example: |
108 * <pre> if (barrier.await() == 0) { |
110 * <pre> {@code |
109 * // log the completion of this iteration |
111 * if (barrier.await() == 0) { |
110 * }</pre> |
112 * // log the completion of this iteration |
|
113 * }}</pre> |
111 * |
114 * |
112 * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model |
115 * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model |
113 * for failed synchronization attempts: If a thread leaves a barrier |
116 * for failed synchronization attempts: If a thread leaves a barrier |
114 * point prematurely because of interruption, failure, or timeout, all |
117 * point prematurely because of interruption, failure, or timeout, all |
115 * other threads waiting at that barrier point will also leave |
118 * other threads waiting at that barrier point will also leave |
202 if (Thread.interrupted()) { |
205 if (Thread.interrupted()) { |
203 breakBarrier(); |
206 breakBarrier(); |
204 throw new InterruptedException(); |
207 throw new InterruptedException(); |
205 } |
208 } |
206 |
209 |
207 int index = --count; |
210 int index = --count; |
208 if (index == 0) { // tripped |
211 if (index == 0) { // tripped |
209 boolean ranAction = false; |
212 boolean ranAction = false; |
210 try { |
213 try { |
211 final Runnable command = barrierCommand; |
214 final Runnable command = barrierCommand; |
212 if (command != null) |
215 if (command != null) |
213 command.run(); |
216 command.run(); |
214 ranAction = true; |
217 ranAction = true; |
215 nextGeneration(); |
218 nextGeneration(); |
216 return 0; |
219 return 0; |
217 } finally { |
220 } finally { |
218 if (!ranAction) |
221 if (!ranAction) |
219 breakBarrier(); |
222 breakBarrier(); |
220 } |
223 } |
221 } |
224 } |
222 |
225 |
223 // loop until tripped, broken, interrupted, or timed out |
226 // loop until tripped, broken, interrupted, or timed out |
224 for (;;) { |
227 for (;;) { |
225 try { |
228 try { |
226 if (!timed) |
229 if (!timed) |
352 */ |
355 */ |
353 public int await() throws InterruptedException, BrokenBarrierException { |
356 public int await() throws InterruptedException, BrokenBarrierException { |
354 try { |
357 try { |
355 return dowait(false, 0L); |
358 return dowait(false, 0L); |
356 } catch (TimeoutException toe) { |
359 } catch (TimeoutException toe) { |
357 throw new Error(toe); // cannot happen; |
360 throw new Error(toe); // cannot happen |
358 } |
361 } |
359 } |
362 } |
360 |
363 |
361 /** |
364 /** |
362 * Waits until all {@linkplain #getParties parties} have invoked |
365 * Waits until all {@linkplain #getParties parties} have invoked |