class Monitor { private boolean locked; public Monitor() { this.locked = true; } public void lock() { this.locked = true; } public void unlock() { this.locked = false; } public boolean isLocked() { return this.locked; } } public class MyClass { // seconds MyClass is willing to wait for a worker to finish executing public static final int WAITTIME = 4; // seconds a Worker takes to execute private static final int RUNTIME = 10; public static void main(String[] args) throws Exception { Monitor monitor = new Monitor(); Worker worker = new Worker(monitor, RUNTIME); System.out.println("MyClass: Worker should timeout after " + WAITTIME + " seconds"); System.out.println("MyClass: starting worker"); worker.start(); synchronized (monitor) { while (monitor.isLocked()) monitor.wait(1000*WAITTIME); } System.out.println("MyClass: done"); } } class Worker extends Thread { // the monitor to notify when finished executing private Monitor monitor; private int runtime; public Worker(Monitor monitor, int runtime) { this.monitor = monitor; this.runtime = runtime; } public void run() { System.out.println("Worker: running for " + runtime + " seconds"); System.out.print("Worker: executing"); try { int count = 0; while (count++ < runtime) { System.out.print(" " + count); Thread.sleep(1000); } } catch (InterruptedException e) {} System.out.println("\nWorker: finished executing"); synchronized (monitor) { System.out.println("Worker: unlocking and notifying supplied monitor"); monitor.unlock(); // to satisfy MyClass loop condition monitor.notify(); } } }