< prev index next >

src/java.base/share/classes/java/util/concurrent/Phaser.java

Print this page
8260664: Phaser.arrive() memory consistency effects
Reviewed-by: martin


 131  * Whenever the number of registered parties of a child phaser becomes
 132  * non-zero (as established in the {@link #Phaser(Phaser,int)}
 133  * constructor, {@link #register}, or {@link #bulkRegister}), the
 134  * child phaser is registered with its parent.  Whenever the number of
 135  * registered parties becomes zero as the result of an invocation of
 136  * {@link #arriveAndDeregister}, the child phaser is deregistered
 137  * from its parent.
 138  *
 139  * <p><b>Monitoring.</b> While synchronization methods may be invoked
 140  * only by registered parties, the current state of a phaser may be
 141  * monitored by any caller.  At any given moment there are {@link
 142  * #getRegisteredParties} parties in total, of which {@link
 143  * #getArrivedParties} have arrived at the current phase ({@link
 144  * #getPhase}).  When the remaining ({@link #getUnarrivedParties})
 145  * parties arrive, the phase advances.  The values returned by these
 146  * methods may reflect transient states and so are not in general
 147  * useful for synchronization control.  Method {@link #toString}
 148  * returns snapshots of these state queries in a form convenient for
 149  * informal monitoring.
 150  *






 151  * <p><b>Sample usages:</b>
 152  *
 153  * <p>A {@code Phaser} may be used instead of a {@code CountDownLatch}
 154  * to control a one-shot action serving a variable number of parties.
 155  * The typical idiom is for the method setting this up to first
 156  * register, then start all the actions, then deregister, as in:
 157  *
 158  * <pre> {@code
 159  * void runTasks(List<Runnable> tasks) {
 160  *   Phaser startingGate = new Phaser(1); // "1" to register self
 161  *   // create and start threads
 162  *   for (Runnable task : tasks) {
 163  *     startingGate.register();
 164  *     new Thread(() -> {
 165  *       startingGate.arriveAndAwaitAdvance();
 166  *       task.run();
 167  *     }).start();
 168  *   }
 169  *
 170  *   // deregister self to allow threads to proceed




 131  * Whenever the number of registered parties of a child phaser becomes
 132  * non-zero (as established in the {@link #Phaser(Phaser,int)}
 133  * constructor, {@link #register}, or {@link #bulkRegister}), the
 134  * child phaser is registered with its parent.  Whenever the number of
 135  * registered parties becomes zero as the result of an invocation of
 136  * {@link #arriveAndDeregister}, the child phaser is deregistered
 137  * from its parent.
 138  *
 139  * <p><b>Monitoring.</b> While synchronization methods may be invoked
 140  * only by registered parties, the current state of a phaser may be
 141  * monitored by any caller.  At any given moment there are {@link
 142  * #getRegisteredParties} parties in total, of which {@link
 143  * #getArrivedParties} have arrived at the current phase ({@link
 144  * #getPhase}).  When the remaining ({@link #getUnarrivedParties})
 145  * parties arrive, the phase advances.  The values returned by these
 146  * methods may reflect transient states and so are not in general
 147  * useful for synchronization control.  Method {@link #toString}
 148  * returns snapshots of these state queries in a form convenient for
 149  * informal monitoring.
 150  *
 151  * <p>Memory consistency effects: Actions prior to any form of arrive
 152  * method <a href="package-summary.html#MemoryVisibility">
 153  * <i>happen-before</i></a> a corresponding phase advance and
 154  * onAdvance actions (if present), which in turn <i>happen-before</i>
 155  * actions following the phase advance.
 156  *
 157  * <p><b>Sample usages:</b>
 158  *
 159  * <p>A {@code Phaser} may be used instead of a {@code CountDownLatch}
 160  * to control a one-shot action serving a variable number of parties.
 161  * The typical idiom is for the method setting this up to first
 162  * register, then start all the actions, then deregister, as in:
 163  *
 164  * <pre> {@code
 165  * void runTasks(List<Runnable> tasks) {
 166  *   Phaser startingGate = new Phaser(1); // "1" to register self
 167  *   // create and start threads
 168  *   for (Runnable task : tasks) {
 169  *     startingGate.register();
 170  *     new Thread(() -> {
 171  *       startingGate.arriveAndAwaitAdvance();
 172  *       task.run();
 173  *     }).start();
 174  *   }
 175  *
 176  *   // deregister self to allow threads to proceed


< prev index next >