for(i=1;i<list.size();i++){
//do something
//For Eg: move marker to a new position on the map
}
我希望以上循环完成所有迭代,而与列表的大小无关,并且还希望整个任务运行1分钟。 (60秒)
我真的不知道这是否是您想要的,但希望对您有所帮助。
import java.util.concurrent.TimeUnit;
for(i=1;i<list.size();i++){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Execute thing you want to be executed every second
}
作为说明:您遍历for循环,并且线程等待一秒钟,然后在TimeUnit.SECONDS.sleep(1);
之后执行代码。如果列表的大小为60,则结束循环将需要一分钟。
编辑:在我看来,围绕睡眠功能进行尝试捕获可能更聪明。
例如,您可以使用System.nanoTime()
来测量循环的持续时间,然后使用TimeUnit.NANOSECONDS.sleep(...)
使其等待其余时间,如下所示:
long start = System.nanoTime();
long desiredDuration = 60 * 1000 * 1000;
// your loop goes here
long duration = System.nanoTime() - start;
if (duration < desiredDuration)
TimeUnit.NANOSECONDS.sleep(desiredDuration - duration);
签出this。
long start = System.currentTimeMillis();
long end = start + 60*1000; // 60 seconds * 1000 ms/sec
int i = 0;
while (System.currentTimeMillis() < end)
{
// do something, check if i less than size of list
i++;
}
不要忘记检查列表的大小。
最佳解决方案是先计算所需的时间,然后在该范围内运行循环。
long finish=System.currentTimeMillis() + 60000;
while(System.currentTimeMillis() != finish)
{
//statements;
//statements;
}
如果您这次尝试配备CPU并使它保持空闲,则该过程称为busy waiting
,但在许多情况下认为不方便,因此我建议为此目的使用Thread.sleep(duration)
。
希望收到您身边的进一步询问。
要在一分钟内均匀分布N
调用量,您必须将两次调用之间的延迟设置为60/(N-1)
值。 -1
是可选的,但会使第一次和最后一次调用恰好相隔60秒。 (就像带有N个梯级的梯子有N-1个空格一样)
当然,将sleep()
与上述计算得出的数字一起使用,不仅会产生舍入误差,而且还会产生漂移,因为您会在延迟之间进行填充,并且填充也会花费时间。
更精确的解决方案是从当前时间中减去每次调用应发生的时间(由startTime + 60*i/(N-1)
定义)。重新排列并重新公式化这些公式,您可以从已经过去的时间中减去“下一次调用应该经历的时间”。
当然,“经过时间”应该使用System.nanoTime()
而不是System.currentTimeMillis()
来计算,因为当时钟改变或计算机从待机状态恢复时,后者可能会跳转。
在此示例中,我将60秒更改为6秒,因此您可以更轻松地查看运行时的情况。
public static void main(String... args) throws Exception { int duration = 6; // seconds List<Double> list = IntStream.range(0, 10).mapToDouble(i->ThreadLocalRandom.current().nextDouble()).boxed().collect(Collectors.toList()); long startTime = System.nanoTime(); long elapsed = 0; for (int i = 0; i < list.size(); i++) { // Bug fixed: start at 0, not at 1. if (i > 0) { long nextInvocation = TimeUnit.NANOSECONDS.convert(duration, TimeUnit.SECONDS) * i / (list.size() - 1); long sleepAmount = nextInvocation - elapsed; TimeUnit.NANOSECONDS.sleep(sleepAmount); } elapsed = System.nanoTime() - startTime; doSomething(elapsed, list.get(i)); } } private static void doSomething(long elapsedNanos, Double d) { System.out.println(elapsedNanos / 1.0e9f + "\t" + d); }
当然,当您为每个列表元素执行的任务所花费的时间超过
60/(N-1)
秒时,您就会出现争用,并且总是会超过“经过的时间”期限。使用此算法,总时间仅需一分钟。但是,如果某些较早的调用超出了截止日期,并且较晚的调用比60/(N-1)
花费的时间少得多,则此算法将显示“追赶”行为。即使sleepAmount
较小,也可以通过休眠至少一个最小量来部分解决此问题。