实时Java,第5部分 - 编写和部署实时Java应用程序 - 编程入门网
,使用 NHRT 进行开发就比较简单。例如,每个生产线轮询线程都将在不朽内存中启动,查询 ProductionLine 之前,要为其预先创建一个作用域。每个筛选池线程都将在不朽内存中启动,并使用栈上的原始数据进行计算。每个线程都将有一个作用域可进入,如果它需要使用 WorkerConsole 接口(对象将在其中创建)。
线程间通信 我们最终的内存问题是如何在线程间通信。ProductionLine 轮询线程需要向筛选池发送数据,筛选池中的每个线程都需要向审计线程传递数据。 通过将原始值作为方法的参数传递就能够轻松解决这个问题。因为所有的数据都将位于栈上,我们就不会遇到关于存储区的问题。 为了使示例应用程序更有趣味性,我们将创建 Measurement 类,其对象将用于度量相关数据。但应在哪个存储区内创建这些对象呢?我们不能使用这个架构,没有任何作用域在线程间共享。 由于忽略了堆和作用域,我们剩下的只有不朽内存。我们知道,不朽内存永远不会还原,因此无法如愿地继续创建 Measurement 对象,因为那样将耗尽内存。答案是:在不朽内存中创建有限个 Measurement 对象,然后重用它们 —— 实际上就是创建了一个对象池。 实时Java,第5部分 - 编写和部署实时Java应用程序(12)时间:2011-06-22 Caroline Gough用 MeasurementManager 轮询度量对象 我们将创建 MeasurementManager 类,它带有一些静态方法,用于获取和返回可重用的 Measurement 实例。作为 Java SE 编程人员,可能会尝试使用一个现有的 LinkedList 或 Queue 类,来提供一个数据存储,容纳我们的度量结果。然而,这种做法不会成功,原因有二:第一个原因是大多数 SE 集合类都在后台创建对象来维护数据结构 —— 比如说链表中的节点,以这种方式创建对象可能导致不朽内存泄漏。第二个原因更为微妙,我们在尝试桥接堆和非堆上下文中运行的线程,对于大多数多线程应用程序,我们需要使用锁来保证对所用一切数据结构的排他访问。这种 NHRT 和基于堆的线程间的锁共享会致使垃圾收集器将 NHRT 作为优先级反转保护的副作用抢占。如果进入垃圾收集器很可能中断了 NHRT 的地方,那么首先就会丧失使用非堆内存的所有收益。可以说,不应在 NHRT 和基于堆的线程间共享锁;关于该问题的具体解释,请参见 “实时 Java,第 3 部分: 线程化和同步”。 RTSJ 提供了一种在 NHRT 和基于堆的线程间共享数据的解决方案,那就是 WaitFreeQueue 类。这些类是具有无等待 端的队列,在这里,一个 NHRT 可以请求读或写某些数据(具体取决于类),而不存在阻塞的风险。队列的另一端使用传统的 Java 同步,由堆线程使用。通过避免非堆和基于堆的环境中的锁,我们就可以安全地交换数据了。 我们的 MeasurementManager 将由 NHRT 用于获取度量结果,由基于堆的审计线程用于返回度量结果。因此,我们使用一个 WaitFreeReadQueue 来管理此结构。WaitFreeQueue 的无等待端专门设计成单线程。WaitFreeReadQueue 则为多个写入方、单一读取方的应用程序而设计。我们使用的是多个读取方、单一写入方的应用程序,因此必须添加自己的同步,来确保同一时间只有一个 NHRT 请求一个度量结果。这看似因添加额外的同步而违背了使用 WaitFreeQueue 的目的。但监控器控制 read() 方法的访问将仅在 NHRT 间共享,因而不会存在堆和非堆上下文中的危险锁共享。 这就带来了 NHRT 应用程序开发中的又一大挑战,为在非堆环境中使用而重用现有部分 Java 代码变得无比艰难。如您所见,您被迫谨慎考虑从何处分配每个对象以及如何避免内存泄漏。总体上来说,Java 语言和面向对象编程的一大优势 —— 实现细节的封装 —— 在非堆环境中变成了一大薄弱环节,因为您 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |