Threads Java

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