在Java中运行x秒的代码?

我想写一个java while循环,它将迭代15秒。 我认为这样做的一种方法是存储当前系统时间+ 15秒,然后将其与while循环签名中的当前时间进行比较。

有没有更好的办法?

这个设计取决于你想要做什么15s。 两个最合理的案例是“每15秒做一次这样的事情”或“等待X发生或15秒即将到来”,这将导致非常不同的代码。

等待

了Thread.sleep(15000)

这不会迭代,但是如果你想为15s做任何事情都会更有效率(它什么都不做会浪费更少的CPU)。

重复一些代码15秒

如果你真的想循环15秒,那么你的解决方案很好,只要你的代码不需要太长时间。 就像是:

long t= System.currentTimeMillis(); long end = t+15000; while(System.currentTimeMillis() < end) { // do something // pause to avoid churning Thread.sleep( xxx ); } 

等待15秒或其他一些条件

如果您希望您的代码在15秒后中断,无论它在做什么,您都需要一个multithreading解决方案。 查看java.util.concurrent以获取许多有用的对象。 大多数锁定的方法(如wait())都有一个超时参数。 信号量可能完全符合您的需求。

正如其他海报已经提到的,如果你只想让线程暂停一段时间,可以使用Thread.sleep()

如果您希望线程执行某些操作,但希望在一段时间后停止,请使用以下内容:

 class Foo implements Runnable { private volatile boolean killed = false; public void run() { while (!killed) { try { doOnce(); } catch (InterruptedException ex) { killed = true; } } } public void kill() { killed = true; } private void doOnce() throws InterruptedException { /* .. */ } } 

并从主线程,做:

 Foo foo = new Foo(); Thread thread = new Thread(foo); thread.start(); /* when you want to stop it */ foo.kill(); thread.interrupt(); 

尝试这个:

 public class SleepMessages { public static void main(String args[]) throws InterruptedException { String importantInfo[] = { "Mares eat oats", "Does eat oats", "Little lambs eat ivy", "A kid will eat ivy too" }; for (int i = 0; i < importantInfo.length; i++) { //Pause for 15 seconds Thread.sleep(15000); //Print a message System.out.println(importantInfo[i]); } } } 

更多信息: 这里

您的一般方法似乎很好,尽管您可能想要查看当前时间是否大于您想要停止的点,否则,您可能会运行很长时间。

另一种方法是运行一个定时器/线程,在15秒后设置一个标志。 此标志必须标记为volatile,否则您的循环可能看不到值中发生的更改。

如果你关心效率的选择哪个更贵,每个循环获得一次系统时间或访问一个volatile变量? 我不知道哪一个更有效率 – 如果真的很重要的话,你可以对它进行基准测试。

对于简单,可维护的代码,我会选择定时器检查方法:

 long endTime = System.currentTimeMillis() + 15000 while (System.currentTimeMillis() < endTime) { //loop } 

您可以使用来自jcabi-aspects的 AOP和@Timeable注释(我是开发人员):

 @Timeable(limit = 1, unit = TimeUnit.SECONDS) String load(String resource) { // do this check regularly: if (Thread.currentThread.isInterrupted()) { throw new IllegalStateException("time out"); } // execution as normal } 

当达到时间限制时,您的线程将被interrupted()标志设置为true ,您的工作是正确处理这种情况并停止执行。

假设您希望循环做一些合理的事情,您可能会发现检查易失性标志会更快。 让另一个线程等待15秒(或使用计时器),然后设置它。

或者,如果您大致知道循环体将花费多长时间,比如运行它几百次,并在外循环中进行检查。

 final long start = System.nanoTime(); do { for (int i=0; i<200, ++i) { ... } } while (System.nanoTime()-start < 15L*1000L*1000L*1000L); 

System.nanoTime不应该被系统时钟更改System.nanoTime糊涂。 使用长字面数字很重要。

您可能有兴趣安排TimerTask来停止另一个线程或更改循环的条件。

切勿在紧密循环中检查当前时间。

否则,有一台笔记本电脑的人可能会被过热的CPU烧掉他/她的膝盖。 我听说过这个故事真的发生了。

有关java.util.concurrent方法,请参阅实践中Java并发的第6章 (第6.3.7节“对任务设置时间限制”,第131页)。

代码示例: 使用时间预算获取广告。

类似于@Tom Hawtin的解决方案,没有仲裁循环大小。

 final long end = System.nanoTime() + 15 * 1000 * 1000 * 1000L; int loop = 1; do { for (int i=0; i 

在这种情况下,内环的尺寸将从小开始,但如果环特别快,则增大尺寸。 如果它足够慢,它可能只迭代一次。

这是我的建议,它对我有用:)

 StoppingTime = 15 ; int loop = 1; long StartTime = System.currentTimeMillis() / 1000 ; for (int i=0; i StoppingTime) loop=0; } 

我建议你用计时器类来避免Thread.sleep(xxx); 方法。

例如:

 import java.util.Timer; import java.util.TimerTask; public class TimerExample { private int globalTimer = 0; private int limitTimer = 15; public static void main(String[] args) { new TimerExample(); } public TimerExample() { Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { globalTimer++; // DO YOUR CODE HERE System.out.println("running"); if (globalTimer == limitTimer) { timer.cancel(); } } }, 0, 1000); } }