java - 在保持同步的同时调度线程 - java

标签 java multithreading concurrency simulator timing

TLDR 我很难同步多线程系统。

我已经实现了一个多线程共享出租车模拟器(速度可调),其中包含一个加权图(其中权重是它花费的时间,以毫秒为单位越过边缘)表示路线图,用户 TaxiPassenger(每个都包含位置和开始时间)。

模拟器的运行是由以下线程创建的:

  1. EventManager:根据开始时间启动实时 Activity (出租车和乘客)。
  2. MatchMaker:在出租车和乘客之间运行匹配算法。
  3. 出租车:每辆出租车都在一个单独的线程上运行,该线程计算出租车的当前位置、接载顺序并搜索最短路径。

问题是随着时间的推移,不同线程之间的时间差不断累积,进而导致模拟器不准确。 例如,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/

相关文章:

java - 如何向调用者线程发出 ExecutorService 已完成任务的信号

java - 基于用户输入的结果

java - 如何在java中为单个线程创建内部线程池

c# - 同步方法中的异步调用

java - Semaphore 的大小可以与Threads 的执行顺序相关吗?

multithreading - 什么是死锁?

java - 我的数据库应用程序已停止工作且无法打开

java - 在Java中解析字符串中的 double 值

Java 构造函数模型

c# - 有什么方法可以确定在 C# 中等待锁定的线程数?