特定持续时间的 Java 循环

2022-09-03 16:40:12

有没有办法让我轻松地在一定时间内进行for循环?(无需使用 System.currentTimeMillis() 来测量时间?

也就是说,我想在Java中做这样的事情:

int x = 0;
for( 2 minutes )  {
   System.out.println(x++);
}

谢谢


答案 1

不,没有内置结构可以做到这一点。

我想指出的是,您不应该使用System.currentTimeMillis()来执行或延迟指定时间段内的任务。而是使用 System.nanoTime()。前一种方法在Windows中是不准确的,而后一种方法无论操作系统如何都是准确的。您可以使用 TimeUnit 枚举轻松地在时间(以毫秒为单位)或任何其他时间单位与时间(以纳秒为单位)之间切换。

for (long stop=System.nanoTime()+TimeUnit.SECONDS.toNanos(2);stop>System.nanoTime();) {
  /*
   * Hammer the JVM with junk
   */
}

答案 2

我认为这是你想要的:

private final Thread thisThread = Thread.current();
private final int timeToRun = 120000; // 2 minutes;

new Thread(new Runnable() {
    public void run() {
        sleep(timeToRun);
        thisThread.interrupt();
    }
}).start();

while (!Thread.interrupted()) {
    // do something interesting.
}

这避免了执行重复的系统调用以获取系统时钟值(这可能相当昂贵),并轮询当前线程的标志(便宜得多)。interrupted

编辑

实际上,除了轮询时钟或轮询标志之外,没有其他安全的替代方案。从理论上讲,您可以修改上述片段以调用已弃用的方法而不是 。Thread.stop()Thread.interrupt()

(我不建议使用和朋友。它们是有缺陷的,使用起来很危险。我只是把它作为一个理论上的替代方案。Thread.stop()

编辑 2

只是要指出,与设置共享标志相比,使用具有优势:Thread.interrupt()

  • Thread.interrupt() 将导致某些阻塞 I/O 和同步方法取消阻塞并引发选中的异常。更新共享标志不会执行此操作。

  • 一些第三方库还会检查中断标志,以查看它们是否应该停止当前正在执行的操作。

  • 如果你的循环涉及对其他方法等的调用,Thread.interrupt()意味着你不需要担心这些方法可以访问标志...如果他们需要的话。

编辑 3

只是为了补充一点,不能保证在几毫秒后唤醒休眠线程。但在正常情况下,它将相当接近。sleep(N)N


推荐