Java tutorial
public class InterruptibleSyncBlock extends Object { private Object longLock; private BooleanLock busyLock; public InterruptibleSyncBlock() { longLock = new Object(); busyLock = new BooleanLock(false); } public void doStuff() throws InterruptedException { print("about to try to get exclusive access " + "to busyLock"); busyLock.waitToSetTrue(0); try { print("about to try to get exclusive access " + "to longLock"); synchronized (longLock) { print("got exclusive access to longLock"); try { Thread.sleep(10000); } catch (InterruptedException x) { // ignore } print("about to relinquish exclusive access " + "to longLock"); } } finally { print("about to free up busyLock"); busyLock.setValue(false); } } private static void print(String msg) { String name = Thread.currentThread().getName(); System.err.println(name + ": " + msg); } private static Thread launch(final InterruptibleSyncBlock sb, String name) { Runnable r = new Runnable() { public void run() { print("in run()"); try { sb.doStuff(); } catch (InterruptedException x) { print("InterruptedException thrown " + "from doStuff()"); } } }; Thread t = new Thread(r, name); t.start(); return t; } public static void main(String[] args) { try { InterruptibleSyncBlock sb = new InterruptibleSyncBlock(); Thread t1 = launch(sb, "T1"); Thread.sleep(500); Thread t2 = launch(sb, "T2"); Thread t3 = launch(sb, "T3"); Thread.sleep(1000); print("about to interrupt T2"); t2.interrupt(); print("just interrupted T2"); } catch (InterruptedException x) { x.printStackTrace(); } } } class BooleanLock extends Object { private boolean value; public BooleanLock(boolean initialValue) { value = initialValue; } public BooleanLock() { this(false); } public synchronized void setValue(boolean newValue) { if (newValue != value) { value = newValue; notifyAll(); } } public synchronized boolean waitToSetTrue(long msTimeout) throws InterruptedException { boolean success = waitUntilFalse(msTimeout); if (success) { setValue(true); } return success; } public synchronized boolean waitToSetFalse(long msTimeout) throws InterruptedException { boolean success = waitUntilTrue(msTimeout); if (success) { setValue(false); } return success; } public synchronized boolean isTrue() { return value; } public synchronized boolean isFalse() { return !value; } public synchronized boolean waitUntilTrue(long msTimeout) throws InterruptedException { return waitUntilStateIs(true, msTimeout); } public synchronized boolean waitUntilFalse(long msTimeout) throws InterruptedException { return waitUntilStateIs(false, msTimeout); } public synchronized boolean waitUntilStateIs(boolean state, long msTimeout) throws InterruptedException { if (msTimeout == 0L) { while (value != state) { wait(); // wait indefinitely until notified } // condition has finally been met return true; } // only wait for the specified amount of time long endTime = System.currentTimeMillis() + msTimeout; long msRemaining = msTimeout; while ((value != state) && (msRemaining > 0L)) { wait(msRemaining); msRemaining = endTime - System.currentTimeMillis(); } // May have timed out, or may have met value, // calculate return value. return (value == state); } }