package sandbox; public class TimeOut implements Runnable { private boolean forceStop; private int timeToRun; private boolean finished; public TimeOut() { forceStop = false; finished = false; } public void demo(int p_timeToWait, int p_timeToRun) { timeToRun = p_timeToRun; Thread t = new Thread(this); forceStop = false; finished = false; t.start(); try { synchronized(t) { trace("Monitor acquired"); t.wait(p_timeToWait); trace("Monitor re-acquired"); } } catch (InterruptedException ie) { trace("Interrupted while waiting for time-out"); } if (t.isAlive() && !finished) { trace("Time out!"); forceStop = true; try { trace("Waiting for effective end of work"); t.join(); trace("End of work reached"); } catch (InterruptedException ie) { trace("Interrupted while waiting for effective end of work"); } } } public void run() { trace("Starting to work"); // détermination du port for(int i = 0; i < 10 && !forceStop; ++i) { try { Thread.sleep(timeToRun / 10); trace("Working..."); } catch (InterruptedException ie) { trace("Interrupted"); } } int remaining = timeToRun - (timeToRun / 10) * 10; if(remaining > 0) { try { Thread.sleep(remaining); } catch (InterruptedException ie) { trace("Interrupted remaining"); } } finished = true; if(!forceStop) { forceStop = false; trace("Notifying end of work"); synchronized (Thread.currentThread()) { Thread.currentThread().notify(); } } trace("End of work"); } private static void trace(String s) { System.out.println(System.currentTimeMillis()+": "+s); } public static void main(String[] argv) { TimeOut to = new TimeOut(); trace("Demo 15, 20"); to.demo(15, 20); trace("==="); trace("Demo 20, 15"); to.demo(20, 15); } }
A remark, the test "t.isAlive()" is not sufficient, because there is no guarantee that run() finishes before wait() is released. Here is a sample output:
javaw.exe -classpath . sandbox.TimeOut 1057702792318: Demo 15, 20 1057702792318: Monitor acquired 1057702792318: Starting to work 1057702792318: Working... 1057702792318: Working... 1057702792318: Working... 1057702792328: Working... 1057702792328: Working... 1057702792328: Working... 1057702792328: Monitor re-acquired 1057702792328: Time out! 1057702792328: Waiting for effective end of work 1057702792328: Working... 1057702792328: End of work 1057702792328: End of work reached 1057702792328: === 1057702792328: Demo 20, 15 1057702792328: Monitor acquired 1057702792328: Starting to work 1057702792338: Working... 1057702792338: Working... 1057702792338: Working... 1057702792338: Working... 1057702792338: Working... 1057702792338: Working... 1057702792338: Working... 1057702792338: Working... 1057702792338: Working... 1057702792338: Working... 1057702792348: Notifying end of work 1057702792348: End of work 1057702792348: Monitor re-acquired
Enjoy!