/** * Created by Christophe De Troyer on 04.11.14. */ public class BarrierSafer { private int _threadcount; private int _releasecount; private final int _threadlimit; private boolean release = false; public BarrierSafer(int threadlimit) { this._threadcount = 0; this._threadlimit = threadlimit; this._releasecount = 0; } public synchronized void joinBarrier(int index) throws InterruptedException { // Wait until we can join. Happens when not all threads have yet left the previous barrier while(_threadcount >= _threadlimit) this.wait(); // will be notified by (A) // Thread got in, increment counter. _threadcount++; if(_threadcount < _threadlimit) { // Wait. Loop to avoid spurious wakeups. while(!release) { this.wait(); // will be notified by (B) } // At this point we have been released, so increment the release counter. _releasecount++; // If we are the last thread to leave, notify the releaseBarrier() that we are gone. if(_releasecount == (_threadlimit - 1)) this.notifyAll(); // (C) why not simply notify? } else { releaseBarrier(); } } public synchronized void releaseBarrier() throws InterruptedException { // Set the release flag to true, so thread can jump out of their wait loop. release = true; // Notify the waiting threads that they can leave. notifyAll(); // (B) // Wait untill the last leaving thread tells us that all threads are gone. while(_releasecount != (_threadlimit - 1)) { this.wait(); // will be notified by (C) } // No more threads can leave. release = false; // Reset the counters. _threadcount = 0; _releasecount = 0; // If threads are waiting to come in, notify them. notifyAll(); // (A) } }