在 Java 中,如何在一段时间后停止执行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4252187/
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
How to stop execution after a certain time in Java?
提问by s2000coder
In the code, the variable timer would specify the duration after which to end the while loop, 60 sec for example.
在代码中,变量 timer 将指定结束 while 循环的持续时间,例如 60 秒。
while(timer) {
//run
//terminate after 60 sec
}
采纳答案by Matt Ball
long start = System.currentTimeMillis();
long end = start + 60*1000; // 60 seconds * 1000 ms/sec
while (System.currentTimeMillis() < end)
{
// run
}
回答by Dmitri
Depends on what the while loop is doing. If there is a chance that it will block for a long time, use TimerTask
to schedule a task to set a stopExecution
flag, and also .interrupt()
your thread.
取决于 while 循环在做什么。如果有可能会阻塞很长时间,请用于TimerTask
安排任务以设置stopExecution
标志,以及.interrupt()
您的线程。
With just a time condition in the loop, it could sit there forever waiting for input or a lock (then again, may not be a problem for you).
在循环中只有一个时间条件,它可以永远坐在那里等待输入或锁定(再说一次,对你来说可能不是问题)。
回答by MBCook
If you can't go over your time limit (it's a hard limit) then a thread is your best bet. You can use a loop to terminate the thread once you get to the time threshold. Whatever is going on in that thread at the time can be interrupted, allowing calculations to stop almost instantly. Here is an example:
如果你不能超过你的时间限制(这是一个硬性限制),那么线程是你最好的选择。一旦达到时间阈值,您可以使用循环来终止线程。当时该线程中发生的任何事情都可以被中断,从而使计算几乎立即停止。下面是一个例子:
Thread t = new Thread(myRunnable); // myRunnable does your calculations
long startTime = System.currentTimeMillis();
long endTime = startTime + 60000L;
t.start(); // Kick off calculations
while (System.currentTimeMillis() < endTime) {
// Still within time theshold, wait a little longer
try {
Thread.sleep(500L); // Sleep 1/2 second
} catch (InterruptedException e) {
// Someone woke us up during sleep, that's OK
}
}
t.interrupt(); // Tell the thread to stop
t.join(); // Wait for the thread to cleanup and finish
That will give you resolution to about 1/2 second. By polling more often in the while loop, you can get that down.
这将使您的分辨率达到大约 1/2 秒。通过在 while 循环中更频繁地轮询,您可以解决这个问题。
Your runnable's run would look something like this:
你的 runnable 的运行看起来像这样:
public void run() {
while (true) {
try {
// Long running work
calculateMassOfUniverse();
} catch (InterruptedException e) {
// We were signaled, clean things up
cleanupStuff();
break; // Leave the loop, thread will exit
}
}
Update based on Dmitri's answer
根据 Dmitri 的回答进行更新
Dmitri pointed out TimerTask, which would let you avoid the loop. You could just do the join call and the TimerTask you setup would take care of interrupting the thread. This would let you get more exact resolution without having to poll in a loop.
Dmitri 指出TimerTask,它可以让你避免循环。您可以只执行 join 调用,您设置的 TimerTask 将负责中断线程。这将使您获得更精确的分辨率,而无需循环轮询。
回答by d0x
you should try the new Java Executor Services. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
您应该尝试新的 Java Executor Services。 http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
With this you don't need to program the loop the time measuring by yourself.
有了这个,你不需要自己编程循环测量时间。
public class Starter {
public static void main(final String[] args) {
final ExecutorService service = Executors.newSingleThreadExecutor();
try {
final Future<Object> f = service.submit(() -> {
// Do you long running calculation here
Thread.sleep(1337); // Simulate some delay
return "42";
});
System.out.println(f.get(1, TimeUnit.SECONDS));
} catch (final TimeoutException e) {
System.err.println("Calculation took to long");
} catch (final Exception e) {
throw new RuntimeException(e);
} finally {
service.shutdown();
}
}
}