有没有办法可以轻松地在一段时间内进行for循环? (不使用System.currentTimeMillis()测量时间?)
即。我想在Java中做这样的事情:
int x = 0;
for( 2 minutes ) {
System.out.println(x++);
}
由于
答案 0 :(得分:24)
不,没有内置的构造可以做到这一点。
我想指出,您不应该使用System.currentTimeMillis()在指定的时间段内执行或延迟任务。而是使用System.nanoTime()。前一种方法在Windows中不准确,而后一种方法无论操作系统如何都是准确的。您可以使用TimeUnit枚举轻松地在毫秒之间或任何其他时间单位之间,以纳秒为单位。
for (long stop=System.nanoTime()+TimeUnit.SECONDS.toNanos(2);stop>System.nanoTime();) {
/*
* Hammer the JVM with junk
*/
}
答案 1 :(得分: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.
}
这避免了重复的系统调用来获取系统时钟值(这可能相当昂贵)并且轮询当前线程的interrupted
标志(更便宜)。
编辑
实际上没有安全替代轮询时钟或轮询标志。理论上,您可以修改上述片段以调用不推荐使用的 Thread.stop()
方法,而不是Thread.interrupt()
。
(我不建议使用Thread.stop()
和朋友。它们存在缺陷,使用起来很危险。我只是将其视为理论替代品。)
编辑2
请注意,使用Thread.interrupt()
优于设置共享标志:
Thread.interrupt()将导致某些阻塞I / O和同步方法解除阻塞并抛出已检查的异常。更新共享标志不会这样做。
某些第三方库也会检查中断标志,看看它们是否应该停止正在进行的操作。
如果你的循环涉及对其他方法的调用等,Thread.interrupt()意味着你不必担心这些方法可以访问标志......如果需要的话。
编辑3
只是要补充说sleep(N)
不能保证在N
毫秒之后唤醒睡眠线程。但在正常情况下,它会相当接近。
答案 2 :(得分:3)
我为这个问题做了一个简单但很糟糕的实现。我想避免使用Timer和TimeTask,最终得到了这个quickfix解决方案。
主要想法是我只是想创建一个独立的倒数计时器,我可以启动并调用isFinished()来检查倒计时是否完成。
package RIPv3;
/**
* Creates a countdown timer which runs its own thread and uses CountdownTimerThread, which runs yet another
* thread.
*
* start() method is called to start the countdown.
* isFinished() method is called to check if the countdown is finished or not.
*
* ! Be Aware!
* This is a quickfix and sucky implementation.
* There will be a small delay. This is not accurate.
*
* @author Endre Vestbø
* @version 1.0 (09.05.2011)
*/
public class CountdownTimer extends Thread {
/* Countdown timer */
private CountdownTimerThread timer;
/**
* Creates a new timer and sets time to count down
* @param time
* Time to count down
*/
public CountdownTimer(long time) {
this.timer = new CountdownTimerThread(time);
}
public void run() {
this.timer.start();
}
/**
* @return
* False if timer is running, else true
*/
public boolean isFinished() {
if(this.timer.getState() == Thread.State.TERMINATED)
return true;
return false;
}
}
package RIPv3;
/**
* Used by CountdownTimer to count down time.
*
* @author Endre Vestbø
* @version 1.0 (09.05.2011)
*
*/
public class CountdownTimerThread extends Thread {
private long time;
/** Create a new timer */
public CountdownTimerThread(long time) {
this.time = time;
}
/**
* Start a countdown
* @param period
* Period to count down given in milliseconds
*/
public void run() {
try {
sleep(this.time);
} catch (InterruptedException e) {
}
}
}
答案 3 :(得分:1)
没有。考虑到简单地编写一个使用System.currentTimeMillis()(或者您选择的任何时间函数)的函数,这是一个奇怪的请求。情况的更多背景可能是有序的。
答案 4 :(得分:1)
这是另一个建议:
public class TimerLoop {
private final AtomicBoolean loop = new AtomicBoolean();
public void run(Runnable runnable, long duration, TimeUnit timeUnit) {
loop.set(true);
TimerTask task = new TimerTask() {
@Override
public void run() {
loop.set(false);
}
};
Timer timer = new Timer();
timer.schedule(task, timeUnit.toMillis(duration));
while (loop.get()) {
runnable.run();
}
}
}
该方法反复执行提供的public void run(Runnable runnable, long duration, TimeUnit timeUnit) {
loop.set(true);
TimerTask task = new TimerTask() {
@Override
public void run() {
loop.set(false);
}
};
Timer timer = new Timer();
timer.schedule(task, timeUnit.toMillis(duration));
while (loop.get()) {
runnable.run();
}
}
的{{1}}方法,直到计时器到期为止。
注意事项:
run()
方法,因为它可能会占用您的所有CPU能力。
Runnable
创建run()
类的新实例,否则实现不是线程安全的。
答案 5 :(得分:0)
我认为没有办法循环一段时间而不检查你是否已经循环了一段时间。
答案 6 :(得分:0)
根据您的使用情况,类Thread 中的两个sleep()方法中的任何一个可能符合条件,但听起来您必须对System.currentTimeMillis()大惊小怪,这看起来很奇怪。
Thread thread = Thread.currentThread();
thread.sleep(10); // 10 milliseconds
thread.sleep(12, 345); // 12 milliseconds and 345 nanoseconds.
答案 7 :(得分:0)
循环迭代值比较,而不是持续时间。因此,如果没有自己分配和比较系统时间,你就无法做到。 如果您希望它是直观的,那么您可以拥有一个内部使用毫秒的函数,但需要Minutes作为参数并使用它。
不,你不能在其中使用线程或睡眠方法,因为这不能确保准确的时间。如果您的处理器在给定时间过后忙于其他一些线程,那么您的线程将继续等待。