在 for 循环中,我通过检索和处理车辆信息来控制基于模拟步骤的交通模拟器 SUMO。为了确保我的程序“实时”模拟(1 个模拟步骤 = 1 秒),我想在处理阶段之后让我的程序休眠,直到下一个时间步骤开始。为了获得更好的结果,我根据最初采用的参考时间戳来计算时间戳。
循环看起来像这样:
System.out.println("start of traffic simulation ...");
for (int i = 0; i < stepCount; i++)
{
System.out.println("step: " + i);
// set before timeStamp
beforeTimeStamp = System.currentTimeMillis();
if (firstStep)
{
// get reference timeStamp
referenceTimeStamp = beforeTimeStamp;
firstStep = false;
}
else
{
// get next vehicleVector
vehicleVector = masterControl.traCIclient.simulateStep();
}
// process vehicleVector
// set after timeStamp
afterTimeStamp = System.currentTimeMillis();
processingTime = afterTimeStamp - beforeTimeStamp;
// calculate sleepTime
sleepTime = referenceTimeStamp + ((i + 1) * 1000) - afterTimeStamp;
// sleep for sleepTime ms
Thread.sleep(sleepTime);
}
System.out.println("end of traffic simulation ...");
这是一些变量的输出:
step: 0
beforeTimeStamp 1252317242565
reference time: 1252317242565
processing time: 394
test time: 1252317243565
afterTimeStamp 1252317242959
sleepTime: 606
step: 1
beforeTimeStamp 1252317242961
processing time: 665
test time: 1252317244565
afterTimeStamp 1252317243626
sleepTime: 939 (exspected: 1000 - 665 = 335)
正如您所看到的,睡眠时间仅对于第一个模拟步骤是正确的。我不知道我在这里会出什么问题。有人有想法吗?
BR,
Markus
You 无法入睡exact使用标准 Java 的时间量这是因为 Java 没有提供关于线程调度的绝对保证。 Java 会受到操作系统分配 CPU 时间的影响,并且您的程序将受到垃圾收集暂停的影响,这是不可预测的。
如果您确实需要可预测的执行,那么您需要查看Java 的实时规范 http://www.rtsj.org/. 这显然是多余的!
您可以使用ScheduledExecutorService
in the java.util.concurrent
包定期执行任务(通过休眠一段时间,或以特定速率执行)。用法:
import static java.util.concurrent.*
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS)
但这是不准确(参见JavaDoc):
但请注意,由于网络时间同步协议、时钟漂移、或其他因素
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)