TransitionDetectorMain.java Source code

Java tutorial

Introduction

Here is the source code for TransitionDetectorMain.java

Source

public class TransitionDetectorMain extends Object {
    private static Thread startTrueWaiter(final TransitionDetector td, String name) {

        Runnable r = new Runnable() {
            public void run() {
                try {
                    while (true) {
                        print("about to wait for false-to-" + "true transition, td=" + td);

                        td.waitForFalseToTrueTransition();

                        print("just noticed for false-to-" + "true transition, td=" + td);
                    }
                } catch (InterruptedException ix) {
                    return;
                }
            }
        };

        Thread t = new Thread(r, name);
        t.start();

        return t;
    }

    private static Thread startFalseWaiter(final TransitionDetector td, String name) {

        Runnable r = new Runnable() {
            public void run() {
                try {
                    while (true) {
                        print("about to wait for true-to-" + "false transition, td=" + td);

                        td.waitForTrueToFalseTransition();

                        print("just noticed for true-to-" + "false transition, td=" + td);
                    }
                } catch (InterruptedException ix) {
                    return;
                }
            }
        };

        Thread t = new Thread(r, name);
        t.start();

        return t;
    }

    private static void print(String msg) {
        String name = Thread.currentThread().getName();
        System.err.println(name + ": " + msg);
    }

    public static void main(String[] args) {
        try {
            TransitionDetector td = new TransitionDetector(false);

            Thread threadA = startTrueWaiter(td, "threadA");
            Thread threadB = startFalseWaiter(td, "threadB");

            Thread.sleep(200);
            print("td=" + td + ", about to set to 'false'");
            td.setValue(false);

            Thread.sleep(200);
            print("td=" + td + ", about to set to 'true'");
            td.setValue(true);

            Thread.sleep(200);
            print("td=" + td + ", about to pulse value");
            td.pulseValue();

            Thread.sleep(200);
            threadA.interrupt();
            threadB.interrupt();
        } catch (InterruptedException x) {
            x.printStackTrace();
        }
    }
}

class TransitionDetector extends Object {
    private boolean value;

    private Object valueLock;

    private Object falseToTrueLock;

    private Object trueToFalseLock;

    public TransitionDetector(boolean initialValue) {
        value = initialValue;
        valueLock = new Object();
        falseToTrueLock = new Object();
        trueToFalseLock = new Object();
    }

    public void setValue(boolean newValue) {
        synchronized (valueLock) {
            if (newValue != value) {
                value = newValue;

                if (value) {
                    notifyFalseToTrueWaiters();
                } else {
                    notifyTrueToFalseWaiters();
                }
            }
        }
    }

    public void pulseValue() {
        // Sync on valueLock to be sure that no other threads
        // get into setValue() between these two setValue()
        // calls.
        synchronized (valueLock) {
            setValue(!value);
            setValue(!value);
        }
    }

    public boolean isTrue() {
        synchronized (valueLock) {
            return value;
        }
    }

    public void waitForFalseToTrueTransition() throws InterruptedException {

        synchronized (falseToTrueLock) {
            falseToTrueLock.wait();
        }
    }

    private void notifyFalseToTrueWaiters() {
        synchronized (falseToTrueLock) {
            falseToTrueLock.notifyAll();
        }
    }

    public void waitForTrueToFalseTransition() throws InterruptedException {

        synchronized (trueToFalseLock) {
            trueToFalseLock.wait();
        }
    }

    private void notifyTrueToFalseWaiters() {
        synchronized (trueToFalseLock) {
            trueToFalseLock.notifyAll();
        }
    }

    public String toString() {
        return String.valueOf(isTrue());
    }
}