Set running time limit on a method in java
As answered of @MarcoS
I found timeout is not raised if method is locking something and not release cpu time to Timer. Then Timer cannot start new thread. So I change a bit by start Thread immediately and sleep inside thread.
InterruptTimerTaskAddDel interruptTimerTask = new InterruptTimerTaskAddDel(
Thread.currentThread(),timeout_msec);
timer.schedule(interruptTimerTask, 0);
/*
* A TimerTask that interrupts the specified thread when run.
*/
class InterruptTimerTaskAddDel extends TimerTask {
private Thread theTread;
private long timeout;
public InterruptTimerTaskAddDel(Thread theTread,long i_timeout) {
this.theTread = theTread;
timeout=i_timeout;
}
@Override
public void run() {
try {
Thread.currentThread().sleep(timeout);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace(System.err);
}
theTread.interrupt();
}
}
I did something similar in the past when spawning an external process with Runtime.getRuntime().exec(command)
. I think you could do something like this within your method:
Timer timer = new Timer(true);
InterruptTimerTask interruptTimerTask = new InterruptTimerTask(Thread.currentThread());
timer.schedule(interruptTimerTask, waitTimeout);
try {
// put here the portion of code that may take more than "waitTimeout"
}
catch (InterruptedException e) {
log.error("timeout exeeded");
}
finally {
timer.cancel();
}
and here is InterruptTimerTask
/*
* A TimerTask that interrupts the specified thread when run.
*/
protected class InterruptTimerTask extends TimerTask {
private Thread theTread;
public InterruptTimerTask(Thread theTread) {
this.theTread = theTread;
}
@Override
public void run() {
theTread.interrupt();
}
}
The Guava library has a very nice TimeLimiter
that lets you do this on any method that's defined by an interface. It can generate a proxy for your object that has a "built-in" timeout.