Java循环持续一段时间

Don*_* Ch 11 java time loops

有没有办法可以轻松地在一段时间内进行for循环?(没有使用System.currentTimeMillis()自己测量时间?)

即我想在Java中做这样的事情:

int x = 0;
for( 2 minutes )  {
   System.out.println(x++);
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Tim*_*der 24

不,没有内置的构造可以做到这一点.

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

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


Ste*_*n C 10

我认为这就是你想要的:

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.
}
Run Code Online (Sandbox Code Playgroud)

这避免了重复的系统调用来获取系统时钟值(这可能相当昂贵)并且轮询当前线程的interrupted标志(更便宜).

编辑

实际上,没有安全的选择来轮询时钟或轮询标志.理论上,您可以修改上面的片段来调用弃用的 Thread.stop()方法而不是Thread.interrupt().

(我建议Thread.stop()和朋友一起使用.它们有缺陷,而且使用起来很危险.我只是把它作为一种理论选择.)

编辑2

只是要指出使用Thread.interrupt()具有优于设置共享标志的优点:

  • Thread.interrupt()将导致某些阻塞I/O和同步方法解除阻塞并抛出已检查的异常.更新共享标志不会这样做.

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

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

编辑3

只是补充说sleep(N),不能保证在完全N毫秒后唤醒睡眠线程.但在正常情况下,它会相当接近.