有没有办法可以轻松地在一段时间内进行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毫秒后唤醒睡眠线程.但在正常情况下,它会相当接近.