CyclicBarrier.java revision a807b4d808d2591894daf13aab179b2e9c46a2f5
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at 4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/ 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent; 88eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilsonimport java.util.concurrent.locks.*; 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A synchronization aid that allows a set of threads to all wait for 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * each other to reach a common barrier point. CyclicBarriers are 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * useful in programs involving a fixed sized party of threads that 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * must occasionally wait for each other. The barrier is called 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <em>cyclic</em> because it can be re-used after the waiting threads 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * are released. 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>A <tt>CyclicBarrier</tt> supports an optional {@link Runnable} command 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that is run once per barrier point, after the last thread in the party 20bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * arrives, but before any threads are released. 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This <em>barrier action</em> is useful 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for updating shared-state before any of the parties continue. 23bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p><b>Sample usage:</b> Here is an example of 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * using a barrier in a parallel decomposition design: 26a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 27a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * <pre> {@code 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class Solver { 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * final int N; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * final float[][] data; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * final CyclicBarrier barrier; 32bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class Worker implements Runnable { 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * int myRow; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Worker(int row) { myRow = row; } 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * public void run() { 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * while (!done()) { 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * processRow(myRow); 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * try { 41bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * barrier.await(); 42bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * } catch (InterruptedException ex) { 43bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * return; 44bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * } catch (BrokenBarrierException ex) { 45bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * return; 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * public Solver(float[][] matrix) { 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * data = matrix; 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * N = matrix.length; 54bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * barrier = new CyclicBarrier(N, 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * new Runnable() { 56bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * public void run() { 57bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * mergeRows(...); 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * }); 60bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * for (int i = 0; i < N; ++i) 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * new Thread(new Worker(i)).start(); 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * waitUntilDone(); 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * } 65a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * }}</pre> 66a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * 67bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Here, each worker thread processes a row of the matrix then waits at the 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * barrier until all rows have been processed. When all rows are processed 69bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the supplied {@link Runnable} barrier action is executed and merges the 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * rows. If the merger 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * determines that a solution has been found then <tt>done()</tt> will return 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <tt>true</tt> and each worker will terminate. 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>If the barrier action does not rely on the parties being suspended when 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * it is executed, then any of the threads in the party could execute that 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * action when it is released. To facilitate this, each invocation of 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link #await} returns the arrival index of that thread at the barrier. 78bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * You can then choose which thread should execute the barrier action, for 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * example: 80a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * <pre> {@code 81a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * if (barrier.await() == 0) { 82a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * // log the completion of this iteration 83a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * }}</pre> 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 85bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>The <tt>CyclicBarrier</tt> uses an all-or-none breakage model 86bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * for failed synchronization attempts: If a thread leaves a barrier 87bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * point prematurely because of interruption, failure, or timeout, all 88bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * other threads waiting at that barrier point will also leave 89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * abnormally via {@link BrokenBarrierException} (or 90bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@link InterruptedException} if they too were interrupted at about 91bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the same time). 92bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 93bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>Memory consistency effects: Actions in a thread prior to calling 94bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@code await()} 95bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a> 96bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * actions that are part of the barrier action, which in turn 97bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <i>happen-before</i> actions following a successful return from the 98bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * corresponding {@code await()} in other threads. 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see CountDownLatch 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class CyclicBarrier { 106bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** 107bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Each use of the barrier is represented as a generation instance. 108bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * The generation changes whenever the barrier is tripped, or 109bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * is reset. There can be many generations associated with threads 110bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * using the barrier - due to the non-deterministic way the lock 111bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * may be allocated to waiting threads - but only one of these 112bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * can be active at a time (the one to which <tt>count</tt> applies) 113bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * and all the rest are either broken or tripped. 114bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * There need not be an active generation if there has been a break 115bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * but no subsequent reset. 116bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 117bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson private static class Generation { 118bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson boolean broken = false; 119bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 120bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** The lock for guarding barrier entry */ 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final ReentrantLock lock = new ReentrantLock(); 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** Condition to wait on until tripped */ 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Condition trip = lock.newCondition(); 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** The number of parties */ 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final int parties; 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* The command to run when tripped */ 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private final Runnable barrierCommand; 129bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson /** The current generation */ 130bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson private Generation generation = new Generation(); 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Number of parties still waiting. Counts down from parties to 0 134bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * on each generation. It is reset to parties on each new 135bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * generation or when broken. 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 137bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson private int count; 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 140bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Updates state on barrier trip and wakes up everyone. 141bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Called only while holding lock. 142bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void nextGeneration() { 144bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson // signal completion of last generation 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project trip.signalAll(); 146bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson // set up next generation 147bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson count = parties; 148bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson generation = new Generation(); 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 152bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Sets current barrier generation as broken and wakes up everyone. 153bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Called only while holding lock. 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void breakBarrier() { 156bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson generation.broken = true; 157bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson count = parties; 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project trip.signalAll(); 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Main barrier code, covering the various policies. 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 164bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson private int dowait(boolean timed, long nanos) 165bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson throws InterruptedException, BrokenBarrierException, 166bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson TimeoutException { 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 170bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson final Generation g = generation; 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 172bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (g.broken) 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new BrokenBarrierException(); 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (Thread.interrupted()) { 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project breakBarrier(); 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new InterruptedException(); 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 180a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson int index = --count; 181a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson if (index == 0) { // tripped 182a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson boolean ranAction = false; 183a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson try { 184a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson final Runnable command = barrierCommand; 185a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson if (command != null) 186a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson command.run(); 187a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson ranAction = true; 188a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson nextGeneration(); 189a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson return 0; 190a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } finally { 191a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson if (!ranAction) 192a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson breakBarrier(); 193a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 194a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 196bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson // loop until tripped, broken, interrupted, or timed out 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (;;) { 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 199bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (!timed) 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project trip.await(); 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project else if (nanos > 0L) 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nanos = trip.awaitNanos(nanos); 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InterruptedException ie) { 204bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (g == generation && ! g.broken) { 205bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson breakBarrier(); 206bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson throw ie; 207bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } else { 208bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson // We're about to finish waiting even if we had not 209bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson // been interrupted, so this interrupt is deemed to 210bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson // "belong" to subsequent execution. 211bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson Thread.currentThread().interrupt(); 212bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson } 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 214bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 215bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (g.broken) 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new BrokenBarrierException(); 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 218bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson if (g != generation) 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return index; 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (timed && nanos <= 0L) { 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project breakBarrier(); 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new TimeoutException(); 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new <tt>CyclicBarrier</tt> that will trip when the 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * given number of parties (threads) are waiting upon it, and which 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will execute the given barrier action when the barrier is tripped, 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * performed by the last thread entering the barrier. 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param parties the number of threads that must invoke {@link #await} 238bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * before the barrier is tripped 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param barrierAction the command to execute when the barrier is 240bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * tripped, or {@code null} if there is no action 241bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws IllegalArgumentException if {@code parties} is less than 1 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public CyclicBarrier(int parties, Runnable barrierAction) { 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parties <= 0) throw new IllegalArgumentException(); 245bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson this.parties = parties; 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.count = parties; 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.barrierCommand = barrierAction; 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new <tt>CyclicBarrier</tt> that will trip when the 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * given number of parties (threads) are waiting upon it, and 253bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * does not perform a predefined action when the barrier is tripped. 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param parties the number of threads that must invoke {@link #await} 256bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * before the barrier is tripped 257bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws IllegalArgumentException if {@code parties} is less than 1 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public CyclicBarrier(int parties) { 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(parties, null); 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the number of parties required to trip this barrier. 265bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 266bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @return the number of parties required to trip this barrier 267bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getParties() { 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return parties; 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 273bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Waits until all {@linkplain #getParties parties} have invoked 274bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <tt>await</tt> on this barrier. 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>If the current thread is not the last to arrive then it is 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * disabled for thread scheduling purposes and lies dormant until 278bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * one of the following things happens: 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>The last thread arrives; or 281bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <li>Some other thread {@linkplain Thread#interrupt interrupts} 282bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the current thread; or 283bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <li>Some other thread {@linkplain Thread#interrupt interrupts} 284bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * one of the other waiting threads; or 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>Some other thread times out while waiting for barrier; or 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>Some other thread invokes {@link #reset} on this barrier. 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 288bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>If the current thread: 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>has its interrupted status set on entry to this method; or 292bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <li>is {@linkplain Thread#interrupt interrupted} while waiting 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * then {@link InterruptedException} is thrown and the current thread's 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interrupted status is cleared. 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 297bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>If the barrier is {@link #reset} while any thread is waiting, 298bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * or if the barrier {@linkplain #isBroken is broken} when 299bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <tt>await</tt> is invoked, or while any thread is waiting, then 300bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@link BrokenBarrierException} is thrown. 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 302bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>If any thread is {@linkplain Thread#interrupt interrupted} while waiting, 303bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * then all other waiting threads will throw 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link BrokenBarrierException} and the barrier is placed in the broken 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * state. 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>If the current thread is the last thread to arrive, and a 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * non-null barrier action was supplied in the constructor, then the 309bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * current thread runs the action before allowing the other threads to 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * continue. 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an exception occurs during the barrier action then that exception 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will be propagated in the current thread and the barrier is placed in 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the broken state. 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the arrival index of the current thread, where index 316bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <tt>{@link #getParties()} - 1</tt> indicates the first 317bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * to arrive and zero indicates the last to arrive 318bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws InterruptedException if the current thread was interrupted 319bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * while waiting 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BrokenBarrierException if <em>another</em> thread was 321bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * interrupted or timed out while the current thread was 322bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * waiting, or the barrier was reset, or the barrier was 323bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * broken when {@code await} was called, or the barrier 324bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * action (if present) failed due an exception. 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int await() throws InterruptedException, BrokenBarrierException { 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return dowait(false, 0L); 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (TimeoutException toe) { 330a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson throw new Error(toe); // cannot happen 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 335bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Waits until all {@linkplain #getParties parties} have invoked 336bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <tt>await</tt> on this barrier, or the specified waiting time elapses. 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>If the current thread is not the last to arrive then it is 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * disabled for thread scheduling purposes and lies dormant until 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * one of the following things happens: 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>The last thread arrives; or 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>The specified timeout elapses; or 344bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <li>Some other thread {@linkplain Thread#interrupt interrupts} 345bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * the current thread; or 346bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <li>Some other thread {@linkplain Thread#interrupt interrupts} 347bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * one of the other waiting threads; or 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>Some other thread times out while waiting for barrier; or 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>Some other thread invokes {@link #reset} on this barrier. 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 351bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>If the current thread: 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul> 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <li>has its interrupted status set on entry to this method; or 355bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <li>is {@linkplain Thread#interrupt interrupted} while waiting 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul> 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * then {@link InterruptedException} is thrown and the current thread's 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interrupted status is cleared. 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 360bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>If the specified waiting time elapses then {@link TimeoutException} 361bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * is thrown. If the time is less than or equal to zero, the 362bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * method will not wait at all. 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 364bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>If the barrier is {@link #reset} while any thread is waiting, 365bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * or if the barrier {@linkplain #isBroken is broken} when 366bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <tt>await</tt> is invoked, or while any thread is waiting, then 367bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * {@link BrokenBarrierException} is thrown. 368bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 369bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <p>If any thread is {@linkplain Thread#interrupt interrupted} while 370bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * waiting, then all other waiting threads will throw {@link 371bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * BrokenBarrierException} and the barrier is placed in the broken 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * state. 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p>If the current thread is the last thread to arrive, and a 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * non-null barrier action was supplied in the constructor, then the 376bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * current thread runs the action before allowing the other threads to 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * continue. 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an exception occurs during the barrier action then that exception 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will be propagated in the current thread and the barrier is placed in 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the broken state. 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param timeout the time to wait for the barrier 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param unit the time unit of the timeout parameter 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the arrival index of the current thread, where index 385bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * <tt>{@link #getParties()} - 1</tt> indicates the first 386bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * to arrive and zero indicates the last to arrive 387bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws InterruptedException if the current thread was interrupted 388bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * while waiting 389bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @throws TimeoutException if the specified timeout elapses 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BrokenBarrierException if <em>another</em> thread was 391bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * interrupted or timed out while the current thread was 392bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * waiting, or the barrier was reset, or the barrier was broken 393bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * when {@code await} was called, or the barrier action (if 394bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * present) failed due an exception 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 396bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson public int await(long timeout, TimeUnit unit) 397bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson throws InterruptedException, 398bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson BrokenBarrierException, 399bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson TimeoutException { 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return dowait(true, unit.toNanos(timeout)); 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Queries if this barrier is in a broken state. 405bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 406bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @return {@code true} if one or more parties broke out of this 407bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * barrier due to interruption or timeout since 408bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * construction or the last reset, or a barrier action 409bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * failed due to an exception; {@code false} otherwise. 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isBroken() { 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 415bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson return generation.broken; 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Resets the barrier to its initial state. If any parties are 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * currently waiting at the barrier, they will return with a 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@link BrokenBarrierException}. Note that resets <em>after</em> 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a breakage has occurred for other reasons can be complicated to 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * carry out; threads need to re-synchronize in some other way, 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and choose one to perform the reset. It may be preferable to 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * instead create a new barrier for subsequent use. 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void reset() { 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 434bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson breakBarrier(); // break the current generation 435bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson nextGeneration(); // start a new generation 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the number of parties currently waiting at the barrier. 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method is primarily useful for debugging and assertions. 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of parties currently blocked in {@link #await} 446bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson */ 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getNumberWaiting() { 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final ReentrantLock lock = this.lock; 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.lock(); 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return parties - count; 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } finally { 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lock.unlock(); 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 457