在java中设置方法的运行时间限制

时间:2011-03-09 08:45:50

标签: java

我有一个返回String的方法,是否有可能在某个时间阈值之后,该方法返回一些特定的字符串?

5 个答案:

答案 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 毫秒