java
java

2008年4月17日

实时Java——为企业级市场热身

实时Java——为企业级市场热身

作者 Simon Ritter译者 韩锴 发布于 2008年4月14日 下午10时3分

社区
Java
主题
性能和扩展性,
实时
标签
JVM

谈到“实时计算(real-time computing)”,人们普遍存在一种误解,即认为“实时系统”一定就是运行得很快的系统,而且几乎只用于机械控制系统。在大多数情况下,实时系统的确需要很快的响应速度,但是仅有“速度”是不足以定义实时系统的。实时环境的真正核心在于,系统必须保证在预定义的时间内执行完指定的任务,这样它的行为才是完全确定的。


对企业级应用程序来说,部署在实时系统上有什么优势(或者劣势)呢?大多数情况下,没有明显的优势。只要满足了非功能性需求(负载能力、平均响应时间、峰值响应时间等),应用程序就可以部署,用户也会觉得满意。有些情况应不应该出现——比如发给HR应用的请求等待响应的时间比普通的用户请求还要长 ——其实它产生的影响并没有一个可以测量的标准。但是,对于大多数金融、企业级应用程序来说,不能在规定的时间内完成某些任务很容易产生其它开销——也许是很大的开销。按照金融市场自己准确的说法,市场是瞬息万变的,计算机交易系统也意味着价格会以每秒钟数次的频率变化。如果系统中的某个部分决定以当前的价格进行一笔交易,但是由于某些原因这笔交易被延迟了,那么价格的一点微小变化也许都会给用户带来巨大的损失。如果这种延迟频繁发生,那说明系统已经是问题重重了。

事实证明,Java语言和Java企业版平台在企业应用程序开发中已经非常流行了。易于开发、性能及可靠性都令Java对开发者充满了诱惑。但是, Java平台并不支持实时应用程序,即使在实时操作系统上运行Java程序,也不能让程序获得更多的确定性。对Java应用程序来说,确定性行为的最大障碍是由Java虚拟机(JVM)托管的内存管理方式。与早期的C和C++这些语言不同,Java使用垃圾回收器来回收那些应用程序不再使用的内存。这样做的原因是为了消除“内存泄露”——程序员忘记显式地释放那些不再使用的内存资源。机器中的内存数量是有限的,如果这个错误出现在某些循环中,那么系统最终会把内存耗尽。(这并不是说,你可以在Java中完全不顾内存泄露的问题;如果开发者占有一个指向对象的引用不释放,垃圾回收器仍然不能回收对象占用的内存)。

垃圾回收器使用一个后台线程监控堆空间的变化,“堆”是存储所有Java对象的场所。垃圾回收器可以识别出不再被引用的对象,并回收空闲出的内存。这些工作大多需要在堆内部将对象从一处复制到另一处。为了防止可能出现的数据崩溃,回收内存时,所有的应用线程(指那些会引起数据变化的线程, mutator threads)都必须暂停。现在的JVM中,由于已经对桌面应用程序进行了高度调优,这些暂停都不易察觉到。甚至对大部分企业级应用程序来说,并行标记扫描(concurrent-mark-sweep)回收器(也叫低暂停回收器,low-pause collector)的应用也已经把暂停降低到了一个大多数应用可以接受的级别上。但不确定行为使Java并不适用于那些类似于前面提到的关键级别企业应用程序。

为了解决这个问题,JCP组织(Java Community Process)创建了一个Java规范请求(JSR),专门用于设计和实现Java的实时规范(RTSJ)。事实上,在起始于1998年的JCP中,它是一个非常早期的JSR。JSR的专家组为规范的创建指定了几条指导原则。当我们考虑企业级应用程序的适用性时,其中的三条原则值得关注:

  1. 向后兼容性。任何兼容的Java编译器生成的类文件都能继续在RTSJ虚拟机上运行。
  2. 不扩展现有的语法。该规范不应该给Java语言增添新的关键字或改变语法。这条原则的部分起因是第一条原则,但为了让Java开发者容易地移植到RTSJ、可以继续使用现有的NetBeans等开发工具,这条原则也是很有必要的。
  3. 可预测的执行行为。这是决策时优先级最高的原则。这条原则有时会影响典型的计算性能有所下降。正是出于这个原因,考虑在通用目的的企业级程序中应用RTSJ时应该格外慎重。

RTSJ详述了扩展了Java语义的八个领域:

  1. 调度(Scheduling)
  2. 内存管理(Memory management)
  3. 同步(Synchronization)
  4. 异步事件处理(Asynchronous event handling)
  5. 异步的控制转移(Asynchronous transfer of control)
  6. 异步终止线程(Asynchronous thread termination)
  7. 访问物理内存(Physical memory access)
  8. 异常(Exceptions)

RTSJ中的线程可以是下述三种类型之一:非实时线程、软实时线程和硬实时线程。非实时线程比较容易理解,因为它不会为某些动作设置必须完成的具体期限。JVM可能在任何方便的时候调度它们,垃圾回收产生的影响也是微不足道的。软实时线程会为动作的完成设置一个最终期限。但它的“最终期限”有一定的回旋余地,因此,即使一个动作比规定的时间稍微晚一些才完成,所有的事情仍然能够正常运行、不会出现任何问题。对硬实时线程来说,它们要求动作必须在最终期限之前完全完成;如果做不到的话,会产生一个不可恢复的(unrecoverable)错误。RTSJ应用程序可以同时运行这三种类型的线程。选择哪种类型的线程,则由应用程序的设计者和适用于线程所做工作的重要级别来决定。下图显示了这些不同类型的线程之间的关系:

图1 RTJS中的线程

典型地,线程要正常工作就必须与应用程序交换数据。由于硬实时线程不能依赖于非实时线程为它实时地发送结果,因此使用一个无等待(wait-free)的数据传送队列可以保证硬实时线程不会被其他线程阻塞。

使用现有的Thread类、不做任何改动,就能创建一个非实时线程。创建软实时线程需要使用RealtimeThread类,它是Thread的子类。这个类的构造函数可以带有可选的优先级参数和释出(release)参数,以此来定义JVM如何调度线程。创建硬实时线程则需要使用 RealtimeThread的子类NoHeapRealtimeThread。从这个类的名称中,你或许能够获得JVM如何实现硬实时线程的一些线索;讨论内存管理的时候,我们还会再详细地讨论这个问题。

把现有的应用程序转化为实时应用程序,最简单的做法就是用RealtimeThread类简单替换发起新线程的代码。虽然这样只把应用程序转为了软实时,但是可以看出,转换过程非常容易。

标准的Java Thread类包含了“优先级”的概念,比起低优先级的线程,优先级高的线程会被优先选择。在RTSJ中,这个概念被进一步扩展了,规范中称,实现必须支持至少28个不同的优先级。因为优先级是用整数表示的,所以规范的实现可以提供更多的优先级别。规范还指出,高优先级线程永远优先于低优先级线程,当更高优先级的线程开始运行时,它会抢占当前运行线程的位置。图2中的类表现了上述信息:

图2 线程执行优先级

PriorityParameters类封装了表示线程优先级的整数。如果多个线程具有相同的优先级,那么可以用一个importance属性与线程关联起来,来指定哪个线程可以获得更大的优先权。

实时系统中有一个很重要的观念:实时系统应该有能力提前判断出它们是否满足应用程序的需求。为了做到这一点,系统必须通过单调速率分析(rate monotonic analysis)知道任务的细节。RTSJ通过释放参数收集这些信息。类的层次结构如图3所示:

图3 释放参数

ReleaseParameters类包含线程的时间开销(这是平台相关的,如果应用程序迁移到不同的平台上,结果也会有变化)、任务必须完成的最终期限,以及处理超出时间开销或错过最终期限这两种情况的处理器。可以处理的线程的类型既可以是周期性的,也可以非周期的,在前面的情况中,线程会按照一个固定的频率重复执行,后者则是线程可以在任何时候启动。如果硬实时系统中包含非周期的任务,这种情况下是不可能分析正确性的,所以引入了“零星任务(sporadic task)”的概念。零星任务为非周期任务分配一个最小频率,这样可以把它当做周期任务对待,从而能够对系统进行分析。将一个非周期任务转化成零星任务并不会改变程序运行的方式,它只是让系统能够判断自己是否满足实时的需求了。

RTSJ还必须实现一种机制,以防止所谓的优先级倒置(priority inversion)现象。图4说明了这个问题:

图4 优先级倒置

就像规范要求的那样,一个低优先级线程(优先级P3)获取了一个对象的锁,会被一个高优先级(优先级P1)的线程夺取执行权。P1线程需要同一个对象上的锁,但是在P3线程释放它之前,P1无法得到锁。其他次高优先级(优先级P2)的线程不断地阻碍P3运行和释放锁。实际看到的效果是P2优先级的线程要优先于P1线程,而这并不是规范里要求的。有两种方法可以避免这种情况。第一种是优先级继承。如果系统检测到P3线程正在持有一个P1线程需要的锁,则会把P3线程的优先级置为P1,直到它释放了锁。这种方法不需要开发者修改任何代码。第二种方法是使用优先级封顶模拟(priority ceiling emulation)。对于第二种方法,开发者必须清楚一个事实:持有锁的线程需要晋升自己的优先级,而且必须在代码中显式地调用来达到这一目的。这种方法在RTSJ中是可选的。

对于内存管理,RTSJ用到了一个“内存域”的概念。它的类结构如图5所示。

图5 实时系统的内存域

由于垃圾回收会引发不确定的暂停,因此所有硬实时线程都必须使用不会受垃圾回收器影响的内存。有两种方法可以做到:Scoped内存和Immortal内存。

Scoped内存就是一块内存,它有一个由应用程序开发者定义的生命期。开发者会创建一个指定大小的Scoped内存域,当实例化一个对象的时候,会从这个域内分配一块空间给它。Scoped内存有两种,线性的(linear)和可变的(variable)——这是指它们实例化一个对象所需的时间。 LTMemory类表示这样的内存域,在这里实例化一个对象的时间等于固定的分配时间加上不定的初始化时间。由于初始化时间直接与对象的大小成比例,因此时间是线性的,而不是常量。VTMemory类表示的内存域则是这样的,其内存分配机制可以使用任何算法,因此时间也是千差万别的。一旦Scoped内存中的所有对象都不再被引用了,它就会被释放以备再次使用。使用Scoped内存的一种场景是:创建Scoped内存域,以供一个 NoHeapRealTimeThread线程使用。当线程执行到所有已知对象都不再被引用的时候,内存域就可以被释放了。

Immortal内存,顾名思义,它永远不会被回收。它被所有线程共享,只有那些开发者确认会随JVM一直存在的对象才适合在这里初始化。

RTSJ规范还允许开发者做一些在标准版Java中不可能办到的事:直接访问物理内存。不过这项功能更多地用于嵌入式实时应用,而不是企业应用,所以本文就不做过多的讨论了。

正如你看到的,RTSJ提供了范围非常广的功能,允许企业级应用程序可以混合运行非实时线程、软实时线程和硬实时线程。对金融系统这种“时间就是金钱”的应用程序来说,可以让临界区的代码做为硬实时线程运行,从而避免垃圾回收器产生的不确定性行为。随着RTSJ 2.0的发布,已经有一个参考实现可用了,它需要在免费可靠的开源Solaris 10操作系统环境下运行,Solaris 10拥有一个实时的调度器(为了在JVM中提供实时的功能,底层的操作系统也必须支持实时的概念)。

企业应用的一个明显趋势是使用具有实时能力的应用服务器。Sun的工程师已经将GlassFish开源应用服务器移植到RTSJ规范上了(在5个小时之内)。IBM也正在加紧开发一款实时的WebSphere产品。当你为企业应用评估是否使用实时Java的时候,请记住:没有免费的午餐。你可能获得了响应时间的保证,但它却会影响到系统的总吞吐量。但是,如果你的Java程序的确、的确不能受垃圾回收的影响,必须要在一定的时间内响应,与其对错误的低概率保有侥幸,不如使用RTSJ。

posted @ 2008-04-17 15:27 nessofblade 阅读(127) | 评论 (0) | 编辑 收藏
 
《新科学家》:十大最不可思议计算机(组图)

据英国《新科学家》杂志报道,现今的计算机技术发展日新月异,但科学家们还是试图拓宽新型计算机的开发领域,近年来研制出光子计算机、量子计算机、DNA计算机等十大不可思议的奇特计算机.

 


光子计算机

1、光子计算机

通过光编码数据并不奇怪,目前全球通讯系统是基于光纤技术。但是使用光信号实际处理数据资料,并进行计算处理却并没有实际应用。

光子计算机是一个值得努力实现的目标,其原因是使用光可增加计算机的处理速度以及可处理的数据质量,但是获得、存储和处理光是非常困难的。像美国伊利诺斯州立大学的保罗?布劳恩等研究人员目前正积极进行该研究。他在光子晶体外建立了3D光学波导,这可能会获得光,使光在锐角转角减缓速度并发生弯曲,而不必担心光的逃逸。

其间,美国哈佛大学的米克海尔?卢金研制了一种光学型晶体管,能够成为现今计算机的能量源。卢金和同事们已建立了使用单一光子从光信号中分离出来的通道,该通道可以转换另一种光信号开启或关闭。


量子计算机

2、量子计算机

如果你想破坏传统计算机计算处理规则,量子计算机将实现这一点。量子计算机不使用1或0的电子比特信息,而采用量子机械效应而建立量子比特。

量子计算机是一类遵循量子力学规律进行高速数学和逻辑运算、存储及处理量子信息的物理装置。当某个装置处理和计算的是量子信息,运行的是量子算法时,它就是量子计算机。量子计算机的概念源于对可逆计算机的研究。研究可逆计算机的目的是为了解决计算机中的能耗问题。

计算显示,量子计算机有能力执行许多平行计算。当量子计算机中量子比特数目增加时,数据将以指数级增长。这将实现现今计算机难以实现的计算处理,比如:快速因式分解较大质数裂化密钥。

然而,量子计算机迄今仅有非常小数目的量子比特,其使用量子圆点、核磁共振、金属离子。


DNA计算机  

3、DNA计算机

DNA将是一种用于执行计算的完美材料,在某种意义上,DNA处理数据和运行程度存储在排序普通碱基对DNA中,处于调整状态蛋白质处理信息就如同DNA有机体维持存活一样。

第一个将DNA用于计算处理的是南加州大学伦纳德?阿德勒曼,1994年,他使用DNA解答了著名的“7点哈密尔敦函数通道”数字问题。从此之后,DNA能够用于建立逻辑门和挑战tic-tac-toe游戏。

由于DNA分子具有强大的并行运算和超高的存储能力,DNA计算将可能解决一些电子计算机难以完成的复杂问题,而且也可能在体内药物传输或遗传分析等领域发挥重要作用。虽然DNA计算未来潜力无穷,但是当前仍然有许多瓶颈技术和基础问题需要解决,其中基于DNA分子的逻辑门就是实现DNA计算的一个重要基础。

近期,DNA计算机的狂热者对建立像人体内的生物学系统非常感兴趣,这样的研究非常有意义,其原因是它的装配性非常好,与传统计算机相比,能够将计算机缩小至最小化,而且便于运行计算处理。


可逆计算机  

4、可逆计算机

许多人思考我们应当循环利用比特,就如同再循环利用垃圾一样。计算机硬件公司长期以来试着减少计算机的能量消耗,一种不同寻常的方法是由“可逆”工程芯片实现的。

正常地每个计算操作会失去一些比特信息,也可表现为丢弃能量。可逆计算机的目标是重新获得并使用这些能量。由美国佛罗里达州立大学迈克尔?弗兰克设计的可逆计算机通过逻辑门能够实现逆行运算。

每一个计算操作包括向逻辑门中输入数据,然后逻辑门出产输出信号,从而代替丢弃能量的信号。弗兰克设计的可逆计算机在每一个计算运行之后逻辑门实现逆行运算,输出信号返回的能量开启执行新的输入信号。


撞球计算机  

5、撞球计算机

数据计算处理可通过光在分子至分子间内部进行连锁反应实现,这对用于一些计算处理的连锁反应非常具有意义,甚至可用于多米诺或大理石弹球进行计算。

这种计算机的逻辑门是由仔细安排的多米诺或斜道石弹球滚动实现的。该计算机虽然比较特殊,但却相当于几英亩大小面积的无数强大微处理器所实现的功能,除非石弹球或多米诺骨牌非常小。IBM公司研究人员采用层叠原子像撞球彼此运行作为逻辑电路,像这样的逻辑门仅能使用一次,但是其意义却意味深长,它比现今最小的晶体管都要小。


神经细胞计算机  

6、神经细胞计算机

当一些研究人员借助已经成功的理念,为什么还称这是计算机技术开发的起跑线呢?目前,研究人员希望能够借助人体的自然力量建造特殊的计算机。

美国芝加哥西北大学费迪南?穆萨?伊瓦尔迪展示了如何利用七鳃鳗的一些脑细胞控制一个机器人。七鳃鳗是一种像鳗鱼的原始脊椎动物。这些脑细胞可控制机器人跟随着光源移动。但这并不是第一次使用动物的大脑进行神经细胞计算机实验。

神经细胞计算机被称为第六代电子计算机,它可以模仿人的大脑判断能力和适应能力,并具有可并行处理多种数据功能的神经网络计算。与以逻辑处理为主的第五代计算机不同,它本身可以判断对象的性质与状态,并能采取相应的行动,而且它可同时并行处理实时变化的大量数据,并引出结论。以往的信息处理系统只能处理条理清晰,经络分明的数据。而人的大脑却具有能处理支离破碎,含糊不清信息的灵活性,神经细胞计算机将具有类似人脑的智慧和灵活性。

目前,美国国防部高级研究计划署通过在飞蛾大脑植入的电极,建立了远程控制的半机械飞蛾。

7、磁共振计算机

每杯水都包含着一台“计算机”,如果你正确理解磁共振运行原理。英国约克大学苏珊?斯特普尼和同事使用强磁场(核磁共振)对分子间的互相影响作用进行控制和观测。这种方法可呈现3D信息,也可使用分子形成互相影响的自然动力学。

如果该理论被证实是可能实现,可使用水分子模拟我们复杂的大气层。迄今为止,研究人员仅能实现该运行计算的理论性,当前只处于基于水的磁共振计算机。

8、Glooper计算机

其中最怪异的就是Glooper计算机,该计算机的建造抛弃了传统计算机的硬件配置,而是通过建立“gloopware”实现运行计算能力。英国西英格兰大学安德鲁?阿达马特兹基能够在化学粘性物质中建立传播离子干扰波,其行为就像形成逻辑门,成为构造计算机的积木块。

这种传播离子干扰波可由一种叫做“Belousov-Zhabotinsky”的脉冲通过循环化学反应生成。阿达马特兹基展示这种化学反应的逻辑门可使一个机器人手臂搅动混合剂,当机器人的手指搅动混合剂刺激化学反应的发生,随后产生的化学反应将控制机器人手臂的运动。

9、霉变计算机

即使像粘土这样的原始有机体也可以用于解决传统计算机的问题,日本名古屋物理化学研究协会Toshiyuki Nakagaki展示粘土的霉变反应可以解决抵达迷宫的最短路径。

这引起了计算机科学家的浓厚兴趣,他们认为粘土的霉变反应可以解决类似于“售货员行程”的问题,在该问题中要求售货员在空间几个售货点之间确定最短的销售行走路程。这种问题在传统计算机上很难实现。

10、水波计算机

或许感觉最不可能实现的就是计算运算能力在水池的波纹中实现。英国苏塞克斯郡大学两位研究人员使用一个波动水箱和一个高架摄像仪,通过波形生成一个“或逻辑门”或“异逻辑门”类型。

posted @ 2008-04-17 15:26 nessofblade 阅读(119) | 评论 (0) | 编辑 收藏
 
Ruby On Rails-2.0.2源代码分析(4)-寻找Controller
     摘要:   前言   经过一番试验和考虑...一,我尝试了一些思维导图工具(MindMapper,FREEMIND),但我始终没有找到一种好的方式将自己学习Rails 源代码的思路表述出来,就此作罢(顺便问问,有研究思维导图的同学么?能否推荐两个自己觉得用起来比较顺手的工具)。二,不再打算整理代...  阅读全文
posted @ 2008-04-17 15:22 nessofblade 阅读(305) | 评论 (0) | 编辑 收藏
 
IDEA上的Groovy插件: JetGroovy 1.5发布

IDEA上的Groovy插件: JetGroovy 1.5发布

 

 

  IntelliJ IDEA的JetGroovy插件是目前最受欢迎的Groovy开发工具之一.前不久这个插件发布了1.5版,这个版本主要对之前版本的一些功能进行扩展:

  @Multiple new Groovy-aware refactorings
  @Extended Groovy coding assistance with support for dynamic properties and methods
  @Groovy-ready debugger that handles mixed Java and Groovy code
  @Smart GroovyDoc browser
  @Support for automatic testing with JUnit/TestNG
  @Improved Grails coding assistance with support for JavaScript and custom tags
  @Complete support for Grails plugins

Debug


code completion


Property and method references in Groovy files
posted @ 2008-04-17 15:18 nessofblade 阅读(295) | 评论 (0) | 编辑 收藏
 
仅列出标题  
 
<2025年7月>
日一二三四五六
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

 导航

  • BlogJava
  • 首页
  • 发新随笔
  • 发新文章
  • 联系
  • 聚合
  • 管理

 统计

  • 随笔: 0
  • 文章: 4
  • 评论: 0
  • 引用: 0

留言簿

  • 给我留言
  • 查看公开留言
  • 查看私人留言

文章档案

  • 2008年4月 (4)

搜索

  •  

最新评论


Powered by: 博客园
模板提供:沪江博客
Copyright ©2025 nessofblade