我有一个返回String的方法,是否有可能在某个时间阈值之后,该方法返回一些特定的字符串?
答案 0 :(得分:14)
Guava library有一个非常好的TimeLimiter
,允许您在接口定义的任何方法上执行此操作。它可以为您的对象生成具有“内置”超时的代理。
答案 1 :(得分:10)
我在使用Runtime.getRuntime().exec(command)
生成外部流程时做了类似的事情。我想你可以在你的方法中做这样的事情:
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();
}
这里是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();
}
}
答案 2 :(得分:1)
回答@MarcoS
我发现如果方法锁定某些内容而不释放CPU时间到Timer,则不会引发超时。 然后Timer无法启动新线程。 所以我立即通过启动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();
}
}
答案 3 :(得分:1)
您可以使用来自@Timeable
的AOP和jcabi-aspects注释(我是开发人员):
@Timeable(limit = 1, unit = TimeUnit.SECONDS)
String load(String resource) {
while (true) {
if (Thread.currentThread.isInterrupted()) {
throw new IllegalStateException("time out");
}
// execution as usual
}
}
当达到时间限制时,你的线程将interrupted()
标志设置为true
,你的工作就是正确处理这种情况并停止执行。
另外,请查看此博文:http://www.yegor256.com/2014/06/20/limit-method-execution-time.html
答案 4 :(得分:0)
这是一个使用 Guava SimpleTimeLimiter
import com.google.common.util.concurrent.SimpleTimeLimiter;
import com.google.common.util.concurrent.TimeLimiter;
import java.time.Duration;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;
class TimeoutExample {
public static void main(String[] args) throws InterruptedException, TimeoutException, ExecutionException {
TimeLimiter timeLimiter = SimpleTimeLimiter.create(Executors.newSingleThreadExecutor());
Duration timeout = Duration.ofMillis(500);
String result = timeLimiter.callWithTimeout(() -> possiblyLongMethod(100), timeout); // will return
System.out.println(result);
String result2 = timeLimiter.callWithTimeout(() -> possiblyLongMethod(1000), timeout); // will timeout
System.out.println(result2);
}
public static String possiblyLongMethod(int runtime) throws InterruptedException {
Thread.sleep(runtime);
return "Ran for " + runtime + "ms";
}
}
第一个调用将成功返回,因为调用只需要 100 毫秒,但第二个调用将失败并返回 TimeoutException
,因为它需要 1000 毫秒