InterruptibleSyncBlock.java Source code

Java tutorial

Introduction

Here is the source code for InterruptibleSyncBlock.java

Source

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