package org.expeditee.core; /** * A Runnable which can be asked to block the calling thread until * execution of the given code has completed. Runnable's run() method * is used as part of the implementation so user code should be specified * by overriding the execute() method instead. * * @author cts16 */ public abstract class BlockingRunnable implements Runnable { /** Whether the code has finished executing or not. */ private boolean _done; /** Synchronisation object to prevent race conditions. */ private Object _lock; public BlockingRunnable() { _done = false; _lock = new Object(); } /** Should be overridden to specify user behaviour. */ public abstract void execute(); @Override public final void run() { execute(); // Mark as finished and wake any blocked threads synchronized (_lock) { _done = true; _lock.notifyAll(); } } /** Can be called to block the calling thread until the execute() method returns. */ public final void blockUntilDone() { synchronized (_lock) { while (!_done) { try { _lock.wait(); } catch (InterruptedException e) { // Do nothing, just try waiting again } } } } }