在CPU指令管道模拟器中管理Java线程

时间:2016-11-30 19:49:05

标签: java multithreading cpu cpu-architecture

我已经使用多线程在Java中实现了一个5阶段CPU指令管道模拟器。

每个阶段都是一个主要执行3个以下功能的线程,每两个阶段之间也有一个队列(容量为1)。

  1. 从上一阶段收到。
  2. 流程即履行其主要职责。
  3. 转发到下一阶段。
  4.     @Override
        public void run() {
            while (!(latchQueue.isEmpty())) {
                fetch();
                process();
                forward();
            }
        }
    

    模拟效果很好。这就是我被困住的地方,我希望能够只模拟指定数量的时钟周期。因此,模拟器应在达到指定的循环次数后停止/暂停。

    截至目前,我已经启动了所有5个线程并让它模拟所有指令的处理,而不是按时钟周期限制它。

    我怎样才能做到这一点?在达到指定的时钟周期时,是否需要暂停线程?如果是这样,我怎样才能优雅地处理暂停/停止线程?请帮助我选择最好的方法。 在此先感谢:)

2 个答案:

答案 0 :(得分:1)

您已经在使用某些并发队列来在线程之间进行通信(确切地说它的工作原理并不清楚,因为您的代码示例非常不完整)。

因此,您可以在第一阶段计算周期,并使用相同的机制进行通信:将一个Sentinel对象推送到第一阶段的队列中,该对象代表"时间停止/暂停此线程"并且在处理时它暂停处理器(并且仍然将其转发到下一阶段,因此所有阶段将逐渐关闭)。例如,您可以扩展队列中传递的对象类型,以便层次结构包含实际有效负载对象(例如,已解码的指令等)或"命令对象"像这样停止/暂停哨兵。

另一个异步解决方案是Thread.interrupt每个线程并在你的处理循环中添加一个中断检查 - 这主要是为了优雅地关闭,而不是支持"暂停&# 34;功能。

答案 1 :(得分:0)

以下工作会怎样?

在代表阶段的所有线程之间共享类CyclesCounter。它有tryReserve方法,从中获取true意味着线程已经为其下一次运行获得了足够的“时钟周期”。获得false意味着没有足够的周期。类是线程安全的。

在获得false之后,或许,你的线程应该停止(即,从run()返回) - 没有办法可以获得足够的周期(由于你的要求,因为我了解他们),直到整个会话再次运行。

class CyclesManager {

    private final AtomicInteger cycles;

    CyclesManager(int initialTotalCycles) {
        if (initialTotalCycles < 0)
            throw new IllegalArgumentException("Negative initial cycles: " + initialTotalCycles);

        cycles = new AtomicInteger(initialTotalCycles);
    }

    /**
     * Tries to reserve given nr of cycles from available total nr of cycles. Total nr is decreased accordingly.
     * Method is thread-safe: total nr of is consistent if called from several threads concurrently.
     *
     * @param cyclesToReserve how many cycles we want
     * @return {@code true} if cycles are ours, {@code false} if not -- there's not enough left
     */
    boolean tryReserve(int cyclesToReserve) {
        int currentCycles = cycles.get();
        if (currentCycles < cyclesToReserve)
            return false;
        return cycles.compareAndSet(currentCycles, currentCycles - cyclesToReserve);
    }

}