Mega Code Archive

 
Categories / Java / Threads
 

Interruptible Synchronized Block

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 );   } }