我应该在Java中使用Java“工作线程"吗?这个CPU模拟应用程序? [英] Should I be using a Java "worker thread" for this CPU simulation app?

查看:100
本文介绍了我应该在Java中使用Java“工作线程"吗?这个CPU模拟应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Java/Swing编写一台旧计算机的仿真器,我认为我已经确定了我遇到的设计问题.尽管此应用程序具有特殊性,但我怀疑有人会找到此问题的模式".

I'm writing an emulator of an old computer in Java/Swing, and I think I've identified the design problem that I'm having. As idiosyncratic as this application is, I suspect someone will find a "pattern" to this problem.

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

I should add that I'm still a beginner at OOP, GUIs, and Design Patterns.

该计算机具有一个GUI线程(控制台)-带按钮和开关,以及一个Model线程(CPU),控制台与之通信以导致控制台事件更改CPU的状态.当然,控制台是由AWT事件队列中的事件驱动的.控制台通过在CPU接收的优先级阻塞队列上排队消息来与CPU通信.这样,CPU也被构造为事件循环.到目前为止,一切都很好.

The machine has a GUI thread (Console) - with pushbuttons and switches, and a Model thread (CPU) with which the Console communicate to cause Console events to change the CPU's state. The Console, of course, is event-driven from the AWT event queue. The Console communicates with the CPU by queueing messages on a Priority Blocking Queue, which the CPU receives. As such, the CPU is structured as an event-loop, too. So far, so good.

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

The problem is that, when you push START on the Console, you want the CPU to start executing whatever program it has in its memory. It still needs to respond to switch throws and button-pushes (such as STOP) from the Console, but it mainly needs to sit there and spin through its instruction fetch-decode-execute loop.

即使有一段时间也没有问题:我有一个名为 Cycle()的方法,该方法将执行当前指令的一个特定周期",然后返回,然后立即将其重新分配给执行下一个循环.我将对Cycle()的调用放置在CPU的运行循环中,并在每个循环后轮询消息队列.如果CPU已停止,则运行循环将仅在消息队列上等待.

And even that wasn't problematic for a while: I had a method called Cycle() that would execute one specific "cycle" of the current instruction and then return, to be immediately redispatched to execute the next cycle. I placed the call to Cycle() inside the CPU's run loop, and polled the message queue after every cycle. If the CPU was stopped, the run loop would simply wait on the message queue.

现在:我正在执行I/O指令,例如读卡.必须有一个周期将数据请求发送到有问题的外围设备(它本身作为在单独线程上运行的GUI/模型来实现),然后 wait 数据到达.这完全打破了CPU的整体概念,它是一个简单的事件循环,可以接收消息并对其进行操作,而不会引起进程阻塞.这个新的周期阻塞.而且,如果操作员还没有在读卡器中装入卡座,则可能会阻塞很长时间.

Now: I'm implementing the I/O instructions, e.g. Read Card. It's necessary for one of the cycles to send a request for data to the peripheral device in question (itself implemented as a GUI/Model running on separate threads) and then wait for the data to arrive. This completely breaks the whole notion of the CPU being a simple event-loop that receives messages and acts upon them without incurring blocking in the process. This new cycle will block. And if the operator hasn't loaded a card deck into the reader, it can block a long time.

我考虑将指令fetch-decode-execute循环分解到一个单独的工作者"线程中,但是我认为这不合适,因为工作线程(据我所知)旨在异步运行完成,并且在运行时不要继续与其父线程进行交互. (实际上,我想不出为什么工作线程"应该永远终止.)而且,当一个循环需要访问可以同时修改为控制台按键的结果.

I thought about factoring the instruction fetch-decode-execute loop out into a separate "worker" thread, but I don't think it's a good fit, since worker threads (as I understand them) are intended to run asynchronously to completion, and do not continue interact with their parent thread while running. (In fact, I can't think of why the "worker thread" should ever terminate.) Also, there is currently no synchronization necessary when a cycle needs to access data that can concurrently be modified as a result of console key presses.

那么我如何设法将事件驱动"处理与传统的批处理过程相融合,而该批处理过程需要在继续操作之前显式等待消息?

So how do I manage to meld "event-driven" processing with a traditional batch-process which needs to explicitly wait for messages before proceeding?

推荐答案

工作线程(据我所知)旨在异步完成运行,并且在运行时不会继续与其父线程进行交互.

Worker threads (as I understand them) are intended to run asynchronously to completion, and do not continue to interact with their parent thread while running.

一个常见的实现, SwingWorker ,没有特别的时间限制,它可以在事件分派中传达结果线程在其生存期内通过publish()方法持续不断地运行.我看到的唯一潜在问题是相应的process()方法可能会收到合并的结果.作为参考,这是一个示例.

A common implementation, SwingWorker, has no particular time limit, and it can communicate results on the event dispatch thread continually during it's lifetime via the publish() method. The only potential problem I see is that the corresponding process() method may receive coalesced results. For reference, here is an example.

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

Alternatively, have your CPU model use a timer to drive the fetch-decode-execute loop. javax.swing.Timer is convenient, as its action event handler executes on the event dispatch thread. You'll have to synchronize access to any shared data using the techniques described in this article.

最后,您可能会看到以下 answer 提到了Java中的6502仿真.

Finally, you might look at this answer that mentions a 6502 emulation in Java.

这篇关于我应该在Java中使用Java“工作线程"吗?这个CPU模拟应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆