Java 设置方法/线程的最长执行时间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20500003/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting a maximum execution time for a method/thread
提问by OneMoreError
I have a method, which writes to the database. The requirement is to make sure that this method does not execute after a certain time elapses. If it returns before that, then nothing should be done.
我有一个方法,它写入数据库。要求是确保该方法在经过一定时间后不执行。如果它在此之前返回,则不应执行任何操作。
The one basic approach that I can think of is doing something like this.
我能想到的一种基本方法是做这样的事情。
public class LimitedRuntime {
public static void writeToDb(){
// writes to the database
}
public static void main(String[] args) {
long totalExecutionTime = 8000L;
long startTime = System.currentTimeMillis();
while(System.currentTimeMillis() - startTime < totalExecutionTime )
{
writeToDb();
}
}
}
One problem with this approach is that even if the method returns before the max total execution time, even then the program halts so as to wait for the time to elapse.
这种方法的一个问题是,即使该方法在最大总执行时间之前返回,程序也会暂停以等待时间过去。
How can I do this better (or maybe more correctly) ? And if we use Thread
, how can we find out which Thread
executes that method ?
我怎样才能做得更好(或更正确)?如果我们使用Thread
,我们如何找出Thread
执行该方法的人?
采纳答案by Andrey Chaschev
You can do this by sending your job to an executor:
您可以通过将您的工作发送给执行人来做到这一点:
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<?> future = executor.submit(new Runnable() {
@Override
public void run() {
writeToDb(); // <-- your job
}
});
executor.shutdown(); // <-- reject all further submissions
try {
future.get(8, TimeUnit.SECONDS); // <-- wait 8 seconds to finish
} catch (InterruptedException e) { // <-- possible error cases
System.out.println("job was interrupted");
} catch (ExecutionException e) {
System.out.println("caught exception: " + e.getCause());
} catch (TimeoutException e) {
future.cancel(true); // <-- interrupt the job
System.out.println("timeout");
}
// wait all unfinished tasks for 2 sec
if(!executor.awaitTermination(2, TimeUnit.SECONDS)){
// force them to quit by interrupting
executor.shutdownNow();
}
}
回答by gvlasov
There is also an AspectJ solution for that with jcabi-aspectslibrary:
还有一个带有jcabi-aspects库的 AspectJ 解决方案:
@Timeable(limit = 5, unit = TimeUnit.SECONDS)
public String writeToDb() {
// writeToDb
}
There is an article explaining it further: Limit Java Method Execution Time
有一篇文章进一步解释了它:限制 Java 方法执行时间