实时Java,第5部分 - 编写和部署实时Java应用程序 - 编程入门网
部接口
系统必须处理三类外部实体:生产线上的称重机、工人的控制台、审计日志。生产线和工人的控制台已封装在系统提供的 Java 接口中。 称重机的接口有一个方法 —— weighJarGrams() —— 它将一直阻塞到下一个罐子传过称重机,并返回该罐子以克数计算的质量。罐子成功传过称重机的比率是变量,但可低至每 10 毫秒 1 个罐子。若 weighJarGrams() 方法未得到足够频繁的轮询,则可能错过某些罐子。 称重机是生产线的一个组件,它具有一些方法,查询所生产的糖果类型以及所填装的罐子规格。 工人的控制台有两个方法 —— jarOverfilled() 和 jarUnderfilled(),两者都要接受一个罐子的 ID。这些方法将阻塞至工人确认消息(可能要花上几秒钟的时间)。 我们将实现 MonitoringSystem 接口,它有两个方法:startMonitoring() 和 stopMonitoring()。startMonitoring() 方法接受 ProductionLine 对象和需要将其作为参数来与之通信的 WorkerConsole 对象。 审计日志被指定为一个名为 audit.log 的平面文件,其中的每一行都是一个以逗号分隔的字符串,格式为 timestamp,jar id,sweet type code, jar size code,mass of jar。 实时Java,第5部分 - 编写和部署实时Java应用程序(9)时间:2011-06-22 Caroline Gough图 6 是一个展示了这些接口的 UML 类图: 图 6. 接口的 UML 类图 设计解决方案 既然已经有了规范,那么就可以设计解决方案了。问题可以分解成两部分:第一,轮询生产线,并检查罐子的质量;第二,写审计日志。 轮询生产线 如果考虑 WeighingMachine 接口,weighJar() 方法需要频繁轮询,因此明智的做法是为每个 ProductionLine 使用一个专用线程,使设计可伸缩。我们将使用一个 NHRT 来最小化轮询被垃圾收集器中断的线程以及丢失度量结果的可能性。 对一个罐子进行称重之后,我们需要计算出该质量等于多少糖果,并将其与目标值相比较。预测一次度量所需进一步处理的数量极为困难,如果一个罐子中的糖果数量超出容许偏差,那么我们就必须考虑与 WorkerConsole 通信,这可能要花上几秒钟的时间。 经过 10 毫秒之后,可能又会有大批罐子传送到此,因此我们显然不能在轮询的线程上进行计算。我们需要将度量结果传递给一个单独的计算线程。由于某些处理可能要占用较长的时间,因而需要为每条生产线使用多个处理线程,确保总有一个线程能来处理最新的度量结果。 可为所产生的每个数据片段生成一个新线程,但这会将大量处理器时间浪费在启动和停止线程上。为更好地利用 CPU 时间,我们可以创建一个 NHRT 池来处理数据,通过维护一个运行中线程的池,在运行的时候就不存在任何线程启动和停止开销了。 可以使用一个由全部生产线共享的线程池,但任何可由多个线程共享的数据结构都需要同步。使用单独一个线程池可能会导致严重的锁争用。为了使我们的解决方案可伸缩,每条生产线都将附有自己的小线程池。 线程池的设计涉及到多方面的考虑事项,例如池的大小和管理技术,这些内容超出了本文讨论范围。就本文的目的而言,我们将为每个 ProductionLine 对象创建 10 个入池线程,如果出于某些原因耗尽线程,我们还会扩展线程池。 实时Java,第5部分 - 编写和部署实时Java应用程序(10)时间:2011-06-22 Caroline Gough写审计日志 与本系统中的其他组件不同,审计日志记录组件并非时间关键的。如果我们(天真地)忽视了计算机崩溃或关闭的可能性,那么惟一重要的考虑事项就是在某些时刻记录的度量结果了。 考虑到这一点,我们将使用一个 java.lang.Thread 来写出到日志文件。在 NHRT 等待更多工作、垃圾收集器不活动时,它将完成这一工作。这样的设计决策具有广泛的影响,原因 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |