Mar*_*kus 3 java simulation multithreading synchronization timestamp
在for-loop中,我通过检索和处理车辆信息来控制基于模拟步骤的交通模拟器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 ...");
Run Code Online (Sandbox Code Playgroud)
这是一些变量的输出:
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,
马库斯
oxb*_*kes 10
你不能睡一个确切的使用标准Java的时间量归因于Java提供有关线程调度没有绝对保障的事实.Java受操作系统分配CPU时间的影响,您的程序将受到无法预测的垃圾收集暂停的影响.
如果确实需要可预测的执行,那么您需要查看Java的实时规范.这里有点过分杀戮!
您可以ScheduledExecutorService
在java.util.concurrent
包中定期执行任务(通过休眠一段时间或以特定速率执行).用法:
import static java.util.concurrent.*
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS)
Run Code Online (Sandbox Code Playgroud)
但这并不准确(参见JavaDoc):
但请注意,由于网络时间同步协议,时钟漂移或其他因素,相对延迟的到期不一定与启用任务的当前日期一致
(强调我的)
归档时间: |
|
查看次数: |
4123 次 |
最近记录: |