我应该为这个CPU模拟应用程序使用Java“工作线程”吗?

时间:2011-07-26 01:02:13

标签: java swing swingworker event-driven

我正在用Java / Swing编写旧计算机的模拟器,我想我已经确定了我遇到的设计问题。由于这个应用程序是特殊的,我怀疑有人会找到这个问题的“模式”。

我应该补充一点,我仍然是OOP,GUI和设计模式的初学者。

机器有一个GUI线程(控制台) - 带有按钮和开关,以及一个模型线程(CPU),控制台与之通信以使控制台事件改变CPU的状态。当然,控制台是从AWT事件队列中事件驱动的。控制台通过在CPU接收的优先级阻塞队列上排队消息来与CPU通信。因此,CPU也被构造为事件循环。到目前为止,非常好。

问题是,当您在控制台上按START时,您希望CPU开始执行其内存中的任何程序。它仍然需要从控制台响应switch switch和button-push(例如STOP),但它主要需要坐在那里并旋转其指令fetch-decode-execute循环。

即便这样也不会有问题:我有一个名为 Cycle()的方法,它会执行当前指令的一个特定“循环”,然后返回,立即重新分配到执行下一个循环。我在CPU的运行循环中调用了Cycle(),并在每个循环后轮询消息队列。如果CPU已停止,则运行循环将只等待消息队列。

现在:我正在实施I / O指令,例如:读卡。其中一个周期必须向相关外围设备发送数据请求(本身实现为在不同线程上运行的GUI /模型),然后 等待 到达的数据。这完全打破了CPU作为一个简单的事件循环的整个概念,它接收消息并对其进行操作而不会在进程中产生阻塞。这个新的循环阻止。如果操作员没有将卡片组装入阅读器,则可能会阻塞很长时间。

我考虑将指令fetch-decode-execute循环分解为一个单独的“worker”线程,但我认为它不适合,因为工作线程(我理解它们)是打算异步运行的< strong>完成,并且在运行时不要继续与其父线程交互。 (事实上​​,我无法想到为什么“工作线程”永远终止。)此外,当一个周期需要访问可以同时修改为的数据时,当前没有必要进行同步。控制台按键的结果。

那么我如何设法将传统批处理过程中的“事件驱动”处理融合在一起,需要在继续之前明确等待消息?

2 个答案:

答案 0 :(得分:2)

在典型的实际系统中,每个独立的设备实际上都是并行运行的(即,在自己的线程上),但在模拟中将其建模为单独的线程当然是有意义的。您需要确保在实际CPU中对中断系统实现某种模拟,以便在工作人员完成其工作时处理同步(例如,新的优先级队列以捕获“I / O中断”等)。您可能会发现Maurice Bach提取The Design of the UNIX Operating System的副本会很有帮助。它详细介绍了UNIX如何与底层硬件交互,并且可能是您项目的良好资源。

答案 1 :(得分:2)

  

工作线程(我理解它们)旨在异步运行以完成,并且在运行时不会继续与其父线程交互。

常见的实施SwingWorker没有特定的时间限制,它可以通过publish()方法在event dispatch thread生命周期内不断地传达结果。我看到的唯一潜在问题是相应的process()方法可能会收到合并结果。作为参考,这是一个example

或者,让您的CPU型号使用计时器来驱动fetch-decode-execute循环。 javax.swing.Timer很方便,因为它的动作事件处理程序在event dispatch thread上执行。您必须使用此article中描述的技术同步对任何共享数据的访问。

最后,您可以看一下这个answer提到Java中的6502仿真。