TLDR 我很难同步多线程系统。
我已经实现了一个多线程共享出租车模拟器(速度可调),其中包含一个加权图(其中权重是它花费的时间,以毫秒为单位越过边缘)表示路线图,用户 Taxi
和Passenger
(每个都包含位置和开始时间)。
模拟器的运行是由以下线程创建的:
EventManager
:根据开始时间启动实时 Activity (出租车和乘客)。MatchMaker
:在出租车和乘客之间运行匹配算法。出租车
:每辆出租车都在一个单独的线程上运行,该线程计算出租车的当前位置、接载顺序并搜索最短路径。
问题是随着时间的推移,不同线程之间的时间差不断累积,进而导致模拟器不准确。
例如,Taxi
可能位于本应花费 x 时间到达的位置,而模拟器的时间为 y ( y >> x )。
我的猜测是,时间差异可能是 CPU 计时的结果,或者是长时间计算和与并发相关的方法(例如 wait()
和 synchronized( )
).
如何确保所有线程以相同的速率工作?
我应该添加延迟以使它们同步吗?
或者在某处添加一个 Timer
?
对于一些线程的主要组件的实现(我删除了不相关的部分以保持问题清晰):
要移动 Taxi
,我会遍历它的路径,并使用边的权重调用 sleep()
(除以模拟器的速度使整个系统在每次迭代中以相同的速率工作):
List<Edge> path;
@Override
public void run(){
Iterator<Edge> itr = path.iterator();
while(itr.hasNext()){
currEdge = itr.next();
sleep(currEdge.getWeight());
}
}
private void sleep(long ms) {
try {
Thread.sleep(sleepTime / Simulator.getSpeed());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
并且 EventManager
通过在事件的时间戳之间 hibernate 来为新事件计时:
Queue<Users> events;
@Override
public void run(){
User nextEvent;
while(!events.isEmpty()){
nextEvent = events.poll();
simulator.start(nextEvent);
sleep(nextEvent);
}
}
private void sleep(User curr) {
if(!events.isEmpty()){
long timeToNextEvent = events.peek().getStartTimeInMS() - curr.getStartTimeInMS();
try {
Thread.sleep(timeToNextEvent / Simulator.getSpeed());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
最佳答案
我不确定这个答案是否有意义,但如果您的问题可以建模为 Discrete Event Simulation (DES),我建议您使用模拟系统时钟。我已经使用并构建了几个 DES 系统,在所有这些系统中,模拟时间都是由一个队列维护的,队列中的元素根据事件时间进行排序。两个事件之间的实时时间当然是瞬时的。
关于java - 在保持同步的同时调度线程 - java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73308611/