Set running time limit on a method in java
I have a method that returns a String.
Is it possible that after a certain time, if threshold is excedeed for that method, to return some specific string?
Solution 1:
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.
Solution 2:
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();
}
}
Solution 3:
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();
}
}
Solution 4:
You can use AOP and a @Timeable
annotation from jcabi-aspects (I'm a developer):
@Timeable(limit = 1, unit = TimeUnit.SECONDS)
String load(String resource) {
while (true) {
if (Thread.currentThread.isInterrupted()) {
throw new IllegalStateException("time out");
}
// execution as usual
}
}
When time limit is reached your thread will get interrupted()
flag set to true
and it's your job to handle this situation correctly and to stop execution.
Also, check this blog post: http://www.yegor256.com/2014/06/20/limit-method-execution-time.html