﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-笨笨的思想片断</title><link>http://www.blogjava.net/zhugf000/</link><description>零碎片断，杂七杂八。</description><language>zh-cn</language><lastBuildDate>Tue, 28 Apr 2026 22:26:46 GMT</lastBuildDate><pubDate>Tue, 28 Apr 2026 22:26:46 GMT</pubDate><ttl>60</ttl><item><title>一个通用的文件配置框架</title><link>http://www.blogjava.net/zhugf000/archive/2008/02/10/179556.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Sun, 10 Feb 2008 07:44:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2008/02/10/179556.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/179556.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2008/02/10/179556.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/179556.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/179556.html</trackback:ping><description><![CDATA[<h1>一个通用的文件配置框架</h1>
<br />
<h2>配置需求说明</h2>
在工作中,项目需要实现多种程序配置方式,每种程序配置均有各自的文件复制,变量替换(替换文本文件中的变量占位符),修改脚本文件的需求. 为减少重复代码,简化配置实现,我们实现了此配置框架.需求片断示例:<br />
<ol>
    <li>复制文件到某处
    <li>创建/append 某个 properties/txt 文本文件
    <li>修改脚本文件,插入一段文本到脚本文件某处
    <li>通过JMX/JNDI连接到远程应用服务器, 用Java code修改应用服务器的配置. </li>
</ol>
<br />
<h2>需求分析</h2>
从上述需求来看,第一印象就是用ANT或类ANT XML文件就可以很好的满足上述需求, 但是还需要做下面增强才会好用:<br />
<ol>
    <li>配置过程需要有类似于事务的机制,以保证多处改动的一致性.
    <li>各种配置过程之间有许多相同之处,为减少重复,可以考虑引入公共配置片断文件.
    <li>由于配置过程相对固定, ANT BUILD XML文件的多个target以及依赖关系检查就不需要了,但是需要更加灵活的条件判断机制来控制单个配置动作和变量赋值. </li>
</ol>
<h2>实现简介</h2>
根据上述分析,项目最终的XML配置文件格式如下:<br />
<font style="background-color: #d4d0c8"><span style="font-size: 10pt; font-family: Courier"><font style="font-family: ; background-color: #d4d0c8">&lt;root&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp; &lt;common&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;resource-bundle&gt;ResourceBundle Message Class&lt;/resource-bundle&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;variables&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- If contains CONFIG_XINFO ,copy it to PLATCODE --&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;variable name="PLATCODE" value="${CONFIG_XINFO}"&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;condition&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;varexists name="CONFIG_XINFO" /&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/condition&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/variable&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- Give it a default value --&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;variable name="IS_WINDOWS" value="FALSE" /&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;variable name="IS_WINDOWS" value="TRUE"&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;condition&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;or&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;variable name="PLATCODE" value="windows"/&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;variable name="PLATCODE" value="windows64"/&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/or&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/condition&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/variable&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/variables&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp; &lt;/common&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp; &lt;configure&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action-invoke<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="CustomizedActionClass"<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index="1"<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action-copy <br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file="${Source File Variable}"<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dest="${Dest file Variable}"<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index="60"<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reason="Error Reason Key"<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action-write<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file="${File to Write}"<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index="20" <br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reason="Error Reason Key"<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;&lt;![CDATA[QUALDIR=${QUALDIR}<br style="font-family: " />
]]&gt;&lt;/action-write&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action-expand <br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file="${File to be expanded}"<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; index="30"<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&gt;<br style="font-family: " />
&nbsp;&nbsp;&nbsp; &lt;/configure&gt;<br style="font-family: " />
&lt;/root&gt;</font><br style="font-family: " />
</span></font><br />
<form>
    与ANT BUILD XML相类似的,分为变量定义区域和配置动作定义区域. 为实现方便,变量可以被覆盖,变量赋值语句可以带条件.<br />
    具体配置过程由多个action-***规定,配置框架已经预提供标准动作: action-copy/action-write/action-expand 等等, action-invoke可以插入自定义Java代码.<br />
    <br />
    <br />
    为了解决问题1,配置框架实现了一套类似于两阶段提交的机制. 每个Action实现类需要实现三个方法:<br />
</form>
<ol>
    <li>Action.performAction(): 实现正常配置动作,如果失败则返回错误码.
    <li>Action.performCompensation(): 实现回滚动作,负责将配置对象(如文件内容)回滚到修改前的状态.
    <li>Action.performComplete(): 实现正常配置完成动作, 负责释放配置过程占用的临时资源.<br />
    </li>
</ol>
配置框架依次对每个要执行的动作调用performAction动作,如果当前Action返回失败错误码,则对已经成功执行的Action反向依次调用 performCompensation动作,执行回滚操作,从而保证配置过程的一致性; 如果全部成功,则依次调用performComplete操作,释放占用的临时资源,如下图:<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/zhugf000/configure_actions.gif" border="0" /><br />
<br />
<br />
为解决问题2,我们为每个action指定了一个index,用它规定执行顺序,配置框架从公共配置文件和私有配置文件中合并并排序所有的配置 action, 通过预先分配common action和private action的index范围, 每个单独的配置过程可以完全抽出重复配置动作.<br />
<br />
为解决问题3, 每个action,每个变量定义(property 标记) 都可以有自己的condition 定义. 如此一来,配置文件的写法更类似于程序的执行过程,从开发角度也更加自然.<br />
<br />
<br />
<h2>其它特性:脚本文件自动分析和插入配置行</h2>
应用服务器的启动脚本是用户可定制的,我们无法预见文件格式. 为解决这个问题,我们采用了如下方式:<br />
<ol>
    <li>对脚本进行语法分析,找出脚本的Java启动行(或Windows Service设置行),进而找出可用的shell变量和插入位置. 期望这种方式能够解决大多数用户自定义脚本.<br />
    <li>对于复杂或分析条件不充分的脚本(如变量位于别的文件), 用户需要在合适位置插入一行有指定格式和参数的注释行(称之为anchor),配置框架会自动在该行后插入配置代码. 这种方式的主要的问题是用户理解困难,项目组支持的工作量大;不过这也是没有办法的办法了.<br />
    </li>
</ol>
<br />
<h2>总结</h2>
本文介绍了一种多文件操作配置框架的思路,并具体解释类事务的配置动作实现过程, 该配置框架在项目实践中达到了预期目的,收到不错的效果.<br />
<br />
<img src ="http://www.blogjava.net/zhugf000/aggbug/179556.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2008-02-10 15:44 <a href="http://www.blogjava.net/zhugf000/archive/2008/02/10/179556.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSRB设计思想－无状态的,粗粒度的SERVICE</title><link>http://www.blogjava.net/zhugf000/archive/2007/12/20/168346.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Thu, 20 Dec 2007 06:23:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2007/12/20/168346.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/168346.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2007/12/20/168346.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/168346.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/168346.html</trackback:ping><description><![CDATA[<h1>JSRB设计思想－无状态的,粗粒度的SERVICE</h1>
出于提高性能和负载均衡实现的考虑，JSRB 采取了无状态的，粗粒度的SERVICE请求和响应机制。<br />
该思想与有状态的ORB(如CORBA或EJB Container)的设计思想截然相反.本文将详述原因.<br />
<br />
<br />
<h2>JSRB定位与想要解决的问题</h2>
JSRB定位于传统的SERVICE REQUEST BROKER地位,就是原始意义上的中间件的位置: 负责将大量客户端(N千或N万)的请求,排队到几十或几百个的请求处理进程(线程)中,最优化的使用系统资源,从而达到吞吐量最大化的目的.<br />
从这个角度来看, EJB Container和CORBA ORB是标准的中间件. Java Web Container由于内建了线程池,也算是中间件(前端协议HTTP,后端协议是JDBC).<br />
<br />
<h2>无状态vs有状态,远程调用的选择.</h2>
有状态要求服务器在远程调用之间保存对应客户端的Session数据,这种设计思想会简化程序代码,有助于将分布式的程序写得更<strong><span style="color: #ff0000;"><span style="color: red;">像</span></span></strong>非分布式程序.<br />
<br />
但是在某些情况下,这种设计会带来严重的性能问题.在金融的在线交易系统中,业务系统需要处理十万至千万级别的用户信息(例如网银系统),而中间件服务器较为合适的session池数量不过万.要在中间件服务器的JVM内存中处理如此巨量的数据,肯定会将系统撑爆; 而如果存储大部分数据到硬盘(钝化技术)来应对,则就会面临IO性能还不如 RDBMS 的窘境. RDBMS 在目前阶段始终是最快速的数据存储方案.<br />
<br />
当业务系统面临大数据量的问题时,需要采用应用相关的解决方案(数据分区,存储过程等等)解决.将问题推给应用服务器固然方便,但是却会带来系统的性能和可扩展性的问题.远程调用的代价本来就很大,不必要让ORB再承担session数据的重担了.与之相反,无状态的远程调用在可扩展性和负载均衡方面的实现要简单得多,也没有session迁移的问题.<br />
<br />
<br />
<h2>SERVICE的粒度问题</h2>
SERVICE远程调用的粒度需要粗一点,在保证SERVICE可重用的前提下,应该尽量减少SERVICE的调用次数, 因为SERVICE的调用开销非常大(一般的远程调用都是以毫秒记,而普通方法的执行时间是以微秒或纳秒为单位的). <br />
有状态SERVICE的一个副作用就是容易出现过细粒度的设计(同时由于Stub/Skeleton的生成很方便,这种设计就更加容易出现了),导致交互次数过多,会严重降低业务系统的性能.<br />
<br />
这方面一个鲜明的对比是大型机的智能终端和telnet协议.智能终端只有等到用户填充完一个表单并确认发送后,才会将请求数据发送到主机,并且自行解释和显示主机返回的数据(非常像Broswer/HTTP), 而telnet协议则将每个按键事件发送到主机,主机处理保存有所有的session数据. 主机可以毫不费劲的处理N万个并发的客户端,而UNIX主机在连接了几千个telnet客户端后,自身的正常运行都会出问题了.<br />
<br />
顺便说一句, 类似的, 从个人项目经历来看, 由于 Hibernate 隐藏JDBC调用很成功,查询或更新数据库非常方便, 程序员就很容易滥用; 有可能导致程序从逻辑上来看毫无问题, 但是运行起来却出现性能低下, 并且这种性能问题还很难改正(性能低下是由于数据库查询过多引起的,要调整的代码遍布整个项目).<br />
<br />
<br />
<h2>其它</h2>
<ol>
    <li>本文的一些思想来源于MidWay(midway.sourceforge.net)和个人的项目经验,仅为一家之言.</li>
    <li>大型项目(企业级)和小项目(部门级)的区别主要就在于,大项目在各个阶段都要将非功能性的要求(性能,容错,恢复,分布式,响应时间,事务等等)放在设计/实现/测试首要考虑的位置,而小项目则几乎无需考虑这样的问题.</li>
    <li>本文和JSRB主要集中在真正的中间层( Service/Object Request Broker/EJB Container).<br />
    </li>
</ol>
<br />
<br />
<img src ="http://www.blogjava.net/zhugf000/aggbug/168346.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2007-12-20 14:23 <a href="http://www.blogjava.net/zhugf000/archive/2007/12/20/168346.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Service Request Broker简介</title><link>http://www.blogjava.net/zhugf000/archive/2007/12/12/167098.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Tue, 11 Dec 2007 16:15:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2007/12/12/167098.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/167098.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2007/12/12/167098.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/167098.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/167098.html</trackback:ping><description><![CDATA[<h1>Java Service Request Broker 简介</h1>
Java Service Request Broker(JSRB)是一个 Java/C/C++ 的开源项目<br />
Project URL http://jsrb.sourceforge.net<br />
<br />
项目目标按照优先顺序依次是:<br />
1 高效,透明的通讯框架,屏蔽本地/远程网络架构的复杂性(高效来源于基于poll/epoll的NIO通讯框架,透明来源于多个JSRB Server之间的动态级联机制).<br />
2 高效率,稳定的服务请求处理机制(高效来源于服务端为C语言实现,稳定来源于对服务进程的不间断监控和自动重启动机制)<br />
3 分布式事务处理能力(JSRB 作为分布式事务管理器,初步实现了DTP XA协议,还在开发过程中).<br />
4 客户端语言中立(语言无关通讯协议,客户端提供Java或C API库).<br />
<br />
JSRB 大致架构如下:<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/zhugf000/jsrb/jsrb_overview.gif" width="796" height="543" /><br />
<br />
<br />
<h2>JSRB SERVICE 特性/访问方式</h2>
1 SERVICE 无状态,通过二进制数据传递输入输出数据<br />
2 运行时,可以有多个SERVICE实现进程, JSRB会平衡调度这些进程.<br />
<br />
SERVICE支持同步/异步两种访问方式:<br />
SERVICE之间也支持forward和嵌套调用两种方式<br />
<br />
同步访问SERVICE: <br />
<em><span style="font-family: Courier;">Response Data = JsrbConection.syncCall("SERVICE NAME",Request Data);</span></em><br />
当客户端从syncCall中返回时,它已经获得SERVICE的返回数据<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/zhugf000/jsrb/jsrb_call_svc.gif" width="412" height="310" /><br />
<br />
<br />
异步访问SERVICE<br />
<em><span style="font-family: Courier;">long key = JsrbConnection.asyncCall("SERVICE",Request Data);<br />
...<br />
Response Data = JsrbConnection.fetchReply(key);<br />
</span></em>客户端可以提交服务请求后,过一段时间再去尝试获取数据, 便衣客户端同时提交多个服务请求,增加并发性.<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/zhugf000/jsrb/jsrb_acall_svc.gif" width="412" height="310" /><br />
<br />
<br />
<br />
SERVICE FORWARD<br />
客户端访问SVC1, SVC1完成后将该请求forward到SVC2, SVC2完成后直接返回客户端数据.<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/zhugf000/jsrb/jsrb_forward_svc.gif" width="412" height="310" /><br />
<br />
<br />
SERVICE的嵌套调用<br />
SVC1 调用SVC2 并获得SVC2的返回数据.<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/zhugf000/jsrb/jsrb_nest_svc.gif" width="668" height="310" /><br />
<br />
<br />
<br />
<br />
<br />
<br />
一般问题:<br />
1 为什么会选择用Java 实现Service Request Broker<br />
答: Java跟C语言相比, 代码执行速度其实并不慢. 我们一般感觉J2EE 应用慢,主要是由于IO(特别是socket和JDBC)慢造成的.<br />
Java 在多线程编程, 开发的方便性方面比C/C++强.<br />
JSRB在实现过程中,自行定义和实现了一套NIO框架, 增加了对于Linux epoll(Edge Triggered Mode)的支持, 同时为了实现与C进程的高效通讯,自行实现了Sysv IPC和创建子进程方面的Native代码.<br />
<br />
<br />
2 为什么要用C实现业务代码,作为Service的实现语言.<br />
从企业端的应用来看, 企业应用必定要跟数据库打交道, 实际上C语言访问数据库要比Java访问数据库快1到两个数量级. 甚至可以说, J2EE应用响应的大部分的延迟时间都耗费在JDBC上. <br />
从大型项目的实施经验来看, 将这部分代码放在C进程中, 尽管要多付出通讯方面的代价,总体还是要比纯Java的方案快得多.<br />
<br />
<br />
3 为什么分布式事务的优先级最低<br />
从大型项目的实施经验来看, 分布式事务由于运行代价过高, 业务系统中用到的概率很小(基本上直接用数据库的事务). 对于CICS/TUXEDO应用而言,首先还是将CICS/TUXEDO 作为一个高效/稳定的通讯和服务请求处理排队框架来用.<br />
如果真要有分布式的交易的需求,一般采用流水对帐+冲正处理方式解决.<br />
<br />
<br />
4 为什么选择无状态方式实现SERVICE<br />
无状态是提高并发效率, 实现透明故障迁移的最佳方式. Server端资源有限,为并发的成千上万个用户同时维护状态是非常困难的,这样也会造成集群实现的困难.<br />
由于Client端是有状态的,所以这在实现上其实问题不大.<br />
<br />
<br />
<br />
今后得空还会慢慢写更多文档介绍JSRB的一些组件的实现方式和特性.<br />
<br />
<br />
<img src ="http://www.blogjava.net/zhugf000/aggbug/167098.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2007-12-12 00:15 <a href="http://www.blogjava.net/zhugf000/archive/2007/12/12/167098.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DTP/XA 规范及XA API调用研究</title><link>http://www.blogjava.net/zhugf000/archive/2007/12/06/165645.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Thu, 06 Dec 2007 06:07:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2007/12/06/165645.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/165645.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2007/12/06/165645.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/165645.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/165645.html</trackback:ping><description><![CDATA[DTP/XA 规范及XA API调用研究<br />
<br />
分布式事务(Distributed Transaction Processing/XA)规范是一个业界标准规范，它定义了分布式事务中各方角色和标准两阶段提交的协议规范(XA Protocol)，该规范为广为业界所支持(CICS/TUXEDO/Enica，后来的OTS/JTS规范以及微软的MTS的莫不源于此。<br />
<br />
XA规范中关键角色简述如下<br />
AP: 客户应用程序，负责连接TM,RM，使用RM的提供的API访问和更改数据，声明分布式事务的开始和结束阶段点(Transaction Demarcation)。<br />
TM: 事务管理器，负责管理、协调、准备和提交分布式事务，对AP的接口标准为TX接口, 并非所有的 TM 实现都遵循这个标准, 但是都会提供类似的接口函数.<br />
RM: 资源管理器，在AP访问数据时，关联事务相关的数据修改，并根据TM的命令提交或回滚数据修改，通常为数据库, IBM MQSeries实现了RM接口。<br />
RM分为静态和动态两种,静态RM需要TM明确调用xa_start/xa_end关联事务与RM的联系. 动态RM在数据发生更改时,会自动回调TM提供的ax_reg/ax_unreg函数,动态关联到当前活动的分布式事务中.<br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/zhugf000/xa/aptmrm.gif" border="0" height="225" width="462" /><br />
<br />
XA API中定义的xa_****和ax_****函数。<br />
ax_reg&nbsp; &nbsp;&nbsp;&nbsp; 向事务管理器注册资源管理器。<br />
ax_unreg &nbsp;&nbsp;&nbsp; 向事务管理器取消注册资源管理器。<br />
xa_close &nbsp;&nbsp;&nbsp; 终止应用程序对资源管理器的使用。<br />
xa_commit &nbsp;&nbsp;&nbsp; 通知资源管理器提交事务分支。<br />
xa_complete &nbsp;&nbsp;&nbsp; 测试异步 xa 操作是否完成。<br />
xa_end &nbsp;&nbsp;&nbsp; 取消线程与事务分支的关联。<br />
xa_forget &nbsp;&nbsp;&nbsp; 允许资源管理器丢弃启发完成的事务分支的信息。<br />
xa_open &nbsp;&nbsp;&nbsp; 初始化资源管理器，供应用程序使用。<br />
xa_prepare &nbsp;&nbsp;&nbsp; 请求资源管理器准备提交事务分支。<br />
xa_recover &nbsp;&nbsp;&nbsp; 获取资源管理器已准备或启发完成的事务标识符 (XID) 列表。<br />
xa_rollback &nbsp;&nbsp;&nbsp; 通知资源管理器回滚事务分支。<br />
xa_start &nbsp;&nbsp;&nbsp; 启动或恢复事务分支；将 XID 与资源管理器请求线程的未来工作关联。<br />
<br />
ax_ 例程可让资源管理器调用事务管理器；所有事务管理器必须提供这些例程。在 DTP 环境中操作时，xa_ 例程由资源管理器提供，并由事务管理器调用。当应用程序调用事务管理器以启动全局事务时，事务管理器可以使用 xa_ 接口通知事务分支的资源管理器。<br />
<br />
分布式事务各个阶段相关API调用如下：<br />
1 AP 通知TM打开RM连接， AP--&gt;TM tx_open()<br />
TM 会在该函数中调用RM提供的xa_open函数，打开到RM的连接。<br />
在TUXEDO SERVICE中，需要在tpsvrinit()函数中调用tpopen()函数完成这项工作。<br />
<br />
2&nbsp;AP 声明事务开始 AP--&gt;TM tx_begin()<br />
在声明后，该线程后续对RM的所有访问和更新均属于该事务。<br />
对于static RM, TM 需要调用xa_start() 明确关联事务和RM。<br />
<br />
在TUXEDO SERVICE/CLIENT中，tpbegin()函数完成类似工作.<br />
当TUXEDO SERVICE被调用时, 如果已经处于事务中, TUXEDO 会自动调用与SERVICE关联的RM的xa_start()函数(只对于 static RM).<br />
<br />
3&nbsp;AP访问RM，使用RM规定的API访问，XA规范未作定义。<br />
对于dynamic RM, 如果访问时发生了数据更改,例如提交一个UPDATE SQL 语句,&nbsp; RM会自动回调TM的ax_reg函数关联到当前事务.<br />
<br />
4 AP声明事务分支结束<br />
在TUXEDO SERVICE调用完成后,&nbsp;自动调用 RM 的xa_end()函数(对于static RM和未调用ax_unreg的dynamic RM)。<br />
<br />
说明: 根据业务需要,上述2-4步骤会在不同的进程(TUXEDO SERVICE)中重复出现, 只要事务ID( Global XID )相同,这多个事务分支(Branch) 均被认为属于同一个事务.<br />
<br />
5&nbsp;AP 要求提交或回滚事务(TM tx_commit/tx_rollback )<br />
AP要求提交事务时, TM 需要检查事务状态, 确定事务并未标记为MARKED_ROLLBACK(只能回滚),否则会回滚并报告错误.<br />
<br />
TUXEDO CLIENT/SERVICE 调用 tpcommit/tpabort 提交或回滚事务.<br />
在TUXEDO中,由于实现的原因,所有xa_prepare/xa_commit/xa_rollback都是由单独的TMS进程发起调用的, TUXEDO SERVICE 进程不会发起相关调用.<br />
TUXEDO配置文件中,每个TUXEDO SERVICE GROUP可以关联一个RM和多个TMS,每个GROUP内的SERVICE 进程和TMS进程启动时都会使用相同的 XA OpenInfo String打开到RM的连接.<br />
<br />
<br />
标准两阶段事务提交过程:<br />
1 (准备)更改事务状态为PREPARING, 依次调用事务关联RM的xa_prepare(), 任意RM返回错误则进入回滚过程, RM都PREPARE完成事务状态改变为PREPARED.<br />
2 (提交)更改事务状态为COMMITTING, 记录事务日志到硬盘中, 依次调用RM的xa_commit方法,再更新事务日志, 更改事务状态为COMMITTED.事务提交完成.<br />
3 (回滚)更改事务状态为ROLLING_BACK, 依次调用事务关联RM的的xa_rollback,更改事务状态为ROLLED_BACK<br />
<br />
简化一阶段事务提交过程:<br />
1&nbsp;(提交)更改事务状态为COMMITTING, 记录事务日志到硬盘中, 调用RM的xa_commit(TMONEPHASE)方法,再更新事务日志, 更改事务状态为COMMITTED.事务提交完成.<br />
<br />
启发式事务提交和回滚:<br />
部分RM支持启发式提交或回滚, xa_commit/xa_rollback 返回时,可能会返回XA_HEUR***的值, 表明RM执行了启发式优化.<br />
此时TM需要后续调用RM的xa_forget(), 让RM彻底释放该事务相关的资源.<br />
<br />
<br />
目前JSRB(Java Service Request Broker)已经部分实现上述TM的功能, 项目继续进展中...: http://jsrb.sourceforge.net<br />
<br />
参考资料：<br />
Distributed Transaction Processing_ The XA Specification<br />
<br />
IBM WebSphere 开发者技术期刊: 在中间件环境中配置和使用 XA<br />
http://www.ibm.com/developerworks/cn/websphere/techjournal/0704_sood/0704_sood.html<br />
<br />
XA接口的一阶段提交与两阶段提交有何区别？
<br />
http://www-1.ibm.com/support/docview.wss?uid=csc148256d65004dc82448256d65004276f0<br />
<br />
<img src ="http://www.blogjava.net/zhugf000/aggbug/165645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2007-12-06 14:07 <a href="http://www.blogjava.net/zhugf000/archive/2007/12/06/165645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>中文全文检索的实现以及一些经验(Java)</title><link>http://www.blogjava.net/zhugf000/archive/2007/07/30/133397.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Mon, 30 Jul 2007 09:55:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2007/07/30/133397.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/133397.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2007/07/30/133397.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/133397.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/133397.html</trackback:ping><description><![CDATA[<h3>中文全文检索的实现以及一些经验(Java)</h3>
<br>
<h3>最近在项目中面临中文全文检索的需求，关键需求如下：</h3>
1 支持中文、英文字词的全文检索，待检索文本是古文言文。<br>2 全文检索表达式支持： AND,OR,NOT,NEAR,BEFORE 运算符，支持()。<br>3 速度要求：400M文本，要求在2-5秒内能够检索完毕。<br><br><br><br>
<h3>尝试Lucene以及放弃原因：</h3>
在尝试Lucene和不同的中文Analyzer后，终告放弃。<br>原因如下：<br>由于待检索文本是古文，中文分词技术无法派上用场。在将分隔存储每个汉字后，发现从Lucene中检索到的文本远远少于关键字实际匹配的文本，这一问题对于较长的检索关键字尤其明显。<br>因为对于检索准确程度要求很高，故此放弃，但是Lucene出的这个问题的原因尚不清楚，希望能够有人提出解答。<br><br><br><br>
<h3>自行实现中文全文检索原理以及方法：</h3>
1 构建过程，忽略标点符号，自行计算每个汉字在每个文本文件中的偏移量，并保存。<br>2 检索过程，定位每个汉字的偏移量，如果检索表达式中每个汉字的预期偏移量与实际偏移量吻合，则匹配成功。<br>3 采用 MappedByteBuffer 加快检索速度，采用二分查找加快偏移量匹配速度，3个左右的关键字复合检索能够在1秒内完成匹配（要求操作系统有足够大的缓存）。<br><br><br>
<h3>目前实现的一些局限和优势：</h3>
0 中文检索速度足够，准确度比Lucene高（如果有高手能够解决这个问题，我会很高兴的废弃掉这些类的）<br>1 合适于中文，不适用英文文本<br>2 全文检索索引文件与原始文本文件的大小大约为2:3-3:4之间，300M大小，比Lucene大约多30M。<br>3 索引文件的构建时间长，400M大约需要3小时，同时由于如果任何文本文件更新，都需要重新构建索引文件，<br>因此不合适要经常变化的文本索引。<br><br><br><br><br>全文检索代码示例(TestFullTextQuery.java)：<br>File storeDir = new File("C:\\temp\\fulltext\\index");<br>StoreSearcher searcher = new StoreSearcher(storeDir);<br>String str = "大?藏 &amp; 阿难"; //同时出现 "大?藏" 和 "阿难"， ?代表任意字符<br>searcher.queryBegin(str, true);<br>while(true){<br>&nbsp;&nbsp;&nbsp; StoreSearcherResult ssr = searcher.getNextQueryResult();<br>&nbsp;&nbsp;&nbsp; if ( ssr == null ){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; System.out.println("ID "+ssr.docId+":"+ssr.matchedCount);<br>}<br>searcher.queryEnd();<br>searcher.close();<br><br>运行结果<br>ID T01n0001.TXT:320<br>ID T01n0002.TXT:3<br>ID T01n0004.TXT:2<br>ID T01n0005.TXT:202<br>ID T01n0006.TXT:131<br>....<br><br><br><br>附：全文检索表达式举例<br><br>关键字中间可以出现?，表明匹配任意字符。<br><br>运算符名称：运算符字符<br>AND:&amp;<br>OR:,<br>BEFORE:*<br>NEAR:+<br>NOT:-<br><br>表达式举例：<br>(KEY1 &lt;AND|OR|BEFORE|NEAR&gt; KEY2) &amp; (NOT KEY3)<br>KEY1 KEY2 (关键字之间无运算符假设为AND)<br><br><br><br>附：全文检索文件格式信息<br><br>DocInfoStore(文档信息)<br>--HEAD--<br>DocCount:Integer&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 文档数目<br>--DOC HEAD(PER DOC)--<br>DocSeq:&nbsp;&nbsp;&nbsp; Integer&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 文档顺序号，内部使用<br>DocId: &nbsp;&nbsp;&nbsp; Char[128]&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 文档唯一ID，字符串格式<br>DocSepOfs: Integer&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 文档分隔符数组的Ofs<br>--DOC SEP OFS(PER DOC)--<br>DocOfs:&nbsp;&nbsp;&nbsp; ArrayOfInteger&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 文档分隔数组<br><br><br>WordInfoStore(每个汉字信息)<br>--HEAD--<br>WordCount:Integer&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 汉字数<br>--WORD IDX(Per Word)--<br>WordChar:Integer&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 汉字的Unicode值<br>WordInfoOfs:Integer&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 汉字信息在文件中的偏移量<br>WordInfoSize:Integer&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 汉字信息大小<br>--WORD INFO(Per Word)--<br>DocCount:&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 汉字出现的文档数<br>DocSeq(Per Doc):&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; 每个文档的顺序号<br>WordInDocs:ArrayOfInteger 每个文档中出现的汉字的偏移数组，从小到大排列<br><br><br>源文件及CLASS下载地址：<br>http://www.blogjava.net/Files/zhugf000/foreader2_ftsearch.zip<br>   <img src ="http://www.blogjava.net/zhugf000/aggbug/133397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2007-07-30 17:55 <a href="http://www.blogjava.net/zhugf000/archive/2007/07/30/133397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在龙芯盒子上编译 Eclipse-3.2.2</title><link>http://www.blogjava.net/zhugf000/archive/2007/03/15/104003.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Thu, 15 Mar 2007 06:06:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2007/03/15/104003.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/104003.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2007/03/15/104003.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/104003.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/104003.html</trackback:ping><description><![CDATA[
		<div>在龙芯盒子上编译 Eclipse-3.2.2</div>
		<div> </div>
		<div>by zhugf 2007/03/15</div>
		<div> </div>
		<div>软件准备：<br />安装 GNOME 开发包 apt-get install libgnome*<br />安装 X11 开发报 apt-get install libxtst*<br />安装 ant 下载 apache-ant-1.7.0<br />准备特别版本 jdk<br />1 将 /usr/lib/jvm/sun-java 复制到本地目录，改名 jdk_1.5.0_142<br />2 从 jdk1.4.2/jre/lib/rt.jar 中找到 java/io/Writer.class 和 java/io/PrintWriter.class， <br />  替换掉 jdk_1.5.0_142/jre/lib/rt.jar 中对应文件</div>
		<div> </div>
		<div>从 <a href="http://dev.lemote.com/projects/eclipsetp/">http://dev.lemote.com/projects/eclipsetp/</a> 用 SVN 下载所需文件</div>
		<div> </div>
		<div> </div>
		<div>设置环境变量：<br />ANT_HOME=apache-ant-1.7.0<br />export ANT_HOME<br />JAVA_HOME=jdk_1.5.0_142<br />export JAVA_HOME<br />PATH=$ANT_HOME/bin:$JAVA_HOME/bin:$PATH<br />export PATH</div>
		<div> </div>
		<div> </div>
		<div> </div>
		<div> </div>
		<div>释放文件：</div>
		<div>
				<div>下载eclipse-sourceBuild-srcIncluded-3.2.2.zip 并解开到某个目录 eclipse-3.2.2</div>
				<div>将 eclipse-src-3.2.2目录下的文件覆盖掉解开的目录下同名的文件</div>
		</div>
		<div> </div>
		<div> </div>
		<div>
				<br />编译：</div>
		<div> </div>
		<div>1 手工编译 Eclipse native 库</div>
		<div> </div>
		<div>cd eclipse-3.2.2/plugins/org.eclipse.core.filesystem/natives/unix/linux</div>
		<div>make</div>
		<div>mkdir ../../../../org.eclipse.core.filesystem.linux.mips32/os/</div>
		<div>mkdir ../../../../org.eclipse.core.filesystem.linux.mips32/os/linux/</div>
		<div>mkdir ../../../../org.eclipse.core.filesystem.linux.mips32/os/linux/mips32</div>
		<div>cp lib*.so ../../../../org.eclipse.core.filesystem.linux.mips32/os/linux/mips32/</div>
		<div> </div>
		<div> </div>
		<div>cd eclipse-3.2.2/plugins/org.eclipse.update.core.linux/src</div>
		<div>ant</div>
		<div> </div>
		<div> </div>
		<div>2 编译 Eclipse</div>
		<div>cd eclipse-3.2.2<br />./build -os linux -ws gtk -arch mips32 -java5home /usr/lib/jvm/sun-java -compilelibs</div>
		<div> </div>
		<div>整个编译过程需要半个小时或更长，编译后目录在： eclipse-3.2.2/eclipse<br />编译时如果出现某个Java文件编译错误，而错误原因是 Eclipse JDT Compiler 内部错误，可以将此文件的头部License注释删除，再重新编译。</div>
		<div> </div>
		<div>3 复制 Eclipse 启动文件</div>
		<div>cd eclipse-3.2.2</div>
		<div>cp launchertmp/eclipse eclipse</div>
		<div> </div>
		<div> </div>
		<div>替换 jar 包：</div>
		<div>编译好后的 eclipse 由于部分文件修改错误，会导致启动失败的问题，这时需要用 eclipse-3.2.2-linux-x86.tgz 文件中的原始文件来替换。</div>
		<div>替换如下文件：</div>
		<div>org.eclipse.osgi_3.2.2.R32x_v20070118.jar<br />org.eclipse.sdk_3.2.2.r322_v20070212<br />org.eclipse.ui.cheatsheets_3.2.1.R321_v20060720.jar<br />org.eclipse.jdt_3.2.1.r321_v20060823.jar<br />org.eclipse.osgi.services_3.1.100.v20060601.jar<br />org.eclipse.osgi.util_3.1.100.v20060601.jar<br />org.eclipse.pde.ui_3.2.1.v20060816-0800.jar<br />org.eclipse.ui.console_3.1.100.v20060605.jar</div>
		<div> </div>
		<div> </div>
		<div> </div>
		<div>文档结束</div>
		<br />
		<img height="768" alt="eclipse_ls2.jpg" src="http://www.blogjava.net/images/blogjava_net/zhugf000/ls2/eclipse_ls2.jpg" width="1024" border="0" />
<img src ="http://www.blogjava.net/zhugf000/aggbug/104003.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2007-03-15 14:06 <a href="http://www.blogjava.net/zhugf000/archive/2007/03/15/104003.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP 程序的国际化/本地化</title><link>http://www.blogjava.net/zhugf000/archive/2006/03/20/36357.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Mon, 20 Mar 2006 08:11:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2006/03/20/36357.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/36357.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2006/03/20/36357.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/36357.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/36357.html</trackback:ping><description><![CDATA[
		<p>前段时间在写一个小程序。用的是 ASP+MSSQL/MYSQL。要求能够同时出简/繁中文版本。<br />就碰到了一些ASP的国际化、本地化的问题，其中的一些处理技巧，与大家共享。</p>
		<p>1 HTML页面、Web应用、ASP 程序源文件全部采用 UTF-8 编码。<br />在文件头部加入行&lt;%@ LANGUAGE=JScript CODEPAGE=65001%&gt;</p>
		<p>2 SQL Server 2000 数据库：<br />    1 数据库字符串字段采用 NVARCHAR/NTEXT/NCHAR Unicode 字符类型。<br />    2 数据库操作SQL 中，字符串全部加 N 前缀： SELECT * FROM TABLE WHERE FIELD LIKE N'中文%' </p>
		<p>3 ASP 程序如果要访问文件，需要用如下代码打开 UTF-16 格式文件：<br />FileSystemObject.OpenTextFile(file,1,false,-1);<br />保证在不同平台下，相同文件都能够正确读取。</p>
		<p>4 ASP 源文件中，不包含任何语言相关字符串，如标题、错误消息。这些消息统一保存到某个文件inc_l10n.asp中。另外，提供一个 inc_strutil.asp 程序，辅助格式化字符串。<br />这样，要更换语言版本，只要更新的 inc_l10n.asp 即可。</p>
		<p>
				<font face="Courier New">inc_l10n.asp<br />&lt;%<br />var l10n_title = "ASP Application Title";<br />var l10n_about= "About ASP Application";<br />var l10n_dict_homename = "HOME NAME";<br />%&gt;</font>
		</p>
		<p>
				<font face="Courier New">inc_strutil.asp:<br />&lt;%<br />//Replace a substring in a String<br />//<br />function replaceAll(data, from, to) {<br />    var buf = "";<br />    var pos = -1;<br />    var i = 0;<br />    while ((pos = data.indexOf(from, i)) != -1) {<br />        buf = buf + (data.substring(i, pos))+ to;<br />        i = pos + from.length;<br />    }<br />    buf = buf + data.substring(i);<br />    return buf;<br />}</font>
		</p>
		<p>
				<font face="Courier New">//return the substitution result from Resource String<br />//Invoke examples: getString("Substitution Example: $1 $2","111","222")<br />//Invoke Result: "Substitution Example: 111 222"<br />function getString()<br />{<br />    if ( arguments.length == 0 )<br />        return "";<br />    if ( arguments.length == 1 )<br />        return ""+arguments[0];<br />    var rawStr = arguments[0];<br />    var i = 0;<br />    for(i=1;i&lt;arguments.length;i++){<br />        rawStr = replaceAll(rawStr,"$"+i,arguments[i]);    <br />    }<br />    return rawStr;<br />}<br />%&gt;<br /></font>
		</p>
<img src ="http://www.blogjava.net/zhugf000/aggbug/36357.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2006-03-20 16:11 <a href="http://www.blogjava.net/zhugf000/archive/2006/03/20/36357.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JVM 内存结构的一张小图</title><link>http://www.blogjava.net/zhugf000/archive/2006/02/06/29695.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Mon, 06 Feb 2006 06:21:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2006/02/06/29695.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/29695.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2006/02/06/29695.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/29695.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/29695.html</trackback:ping><description><![CDATA[<P><A HREF="/images/blogjava_net/zhugf000/jvm_mem.gif"><IMG height=457 alt=jvm_mem.gif src="http://www.blogjava.net/images/blogjava_net/zhugf000/jvm_mem.gif" width=391 border=0></A></P><img src ="http://www.blogjava.net/zhugf000/aggbug/29695.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2006-02-06 14:21 <a href="http://www.blogjava.net/zhugf000/archive/2006/02/06/29695.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>架构师的工作</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/17/24403.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Sat, 17 Dec 2005 12:13:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/17/24403.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/24403.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/17/24403.html#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/24403.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/24403.html</trackback:ping><description><![CDATA[<B>架构师的工作</B><BR><BR>就笨笨所理解，其实很简单：<BR>1 把意图表达出来，主要做法是画图。<BR>2 把意图贯彻下去，主要做法是喷，对象是项目组、客户、公司领导。<BR><BR><IMG height=577 alt=arch_fig1.gif src="http://www.blogjava.net/images/blogjava_net/zhugf000/arch_fig1.gif" width=502 border=0><BR><BR><BR><B>业务架构的目标</B><BR><BR>按照优先级排列<BR>1 固化开发和测试模式，减小开发人员的自由发挥余地，从而做到：<BR>&nbsp;&nbsp; &nbsp;1 将业务代码实现简单化和固定化，降低对开发人员的技术要求（如要求了解J2EE框架或HTTP交互过程等）<BR>&nbsp;&nbsp; &nbsp;2 复用开发人员的经验，在下个使用业务架构的项目中，不需要再行学习<BR><BR>2 减少项目的基础性<STRONG>技术代码</STRONG>开发工作和步骤，这里的技术代码，指与业务无关的部分，如配置、日志、文件上传、ORM 等等。这个目标需要在组织级维护跨项目的<STRONG>技术框架</STRONG>，单靠个人是无法做到的。<BR><BR>3 实现对项目的<STRONG>业务代码</STRONG>的重用。这个目标几乎不可能实现，业务代码重用的前提是它经过业务专家的提炼、业务过程完整、可完全配置。假如这个目标能够实现，那么开发人员的角色类似于 SAP 实施人员，主要工作是配置，而不是写代码。<BR><BR><BR><BR><BR><B>国内公司的业务架构实现的困境</B><BR><BR>对于国内公司来说，由于中长期利益与短期利益的冲突，架构一般很难坚持下去。<BR>国内公司限于成本压力，经常会要求架构师在项目中实现业务框架；但是这个目标与项目的直接目标是有冲突的。<BR><BR>业务框架为了达到可重用的目标，是需要比项目完成要多做好多工作的，如框架文档、辅助工具等等，这需要大量的开发工作量，会与项目的直接目标发生冲突，而冲突出现时，公司和项目经理一般都会选择牺牲重用的业务框架这个目标，保证项目的完成。 在项目完成后，公司也很少单独组织人力对项目成果进行评估和重构，结果最终还是得不到一个重用的业务框架。<BR><BR><img src ="http://www.blogjava.net/zhugf000/aggbug/24403.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-17 20:13 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/17/24403.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于J2EE的业务产品/框架(PPT)</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/15/24007.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Thu, 15 Dec 2005 04:49:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/15/24007.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/24007.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/15/24007.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/24007.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/24007.html</trackback:ping><description><![CDATA[笨笨10月份写的一个自我小结的大纲，缺乏开发模式的部分。<br>点击<a HREF="/Files/zhugf000/j2ee_based_frame.zip">这里</a>下载。<br><br><br><div align="center"><b><font size="5">提纲</font></b><br></div><p:colorscheme colors="#FFFFFF,#000000,#808080,#000000,#BBE0E3,#333399,#009999,#99CC00">

</p:colorscheme><div v:shape="_x0000_s1026">

<div class="O" style=""><span style="font-family: &quot;Courier New&quot;; font-size: 133%;"><span style="position: absolute; left: -5.44%;">•</span></span><font size="2"><span style="font-family: 宋体; font-size: 24pt;"></span></font></div></div>技术产品与业务产品的差别比较<br><img src="http://www.blogjava.net/images/blogjava_net/zhugf000/j2ee_frame/j2ee_frame_fig1.gif" alt="j2ee_frame_fig1.gif" border="0" height="440" width="669"><br>业务产品的结构层次与实现重点<br><img src="http://www.blogjava.net/images/blogjava_net/zhugf000/j2ee_frame/j2ee_frame_fig2.gif" alt="j2ee_frame_fig2.gif" border="0" height="393" width="587"><br><img src="/zhugf000/admin/FtbWebResource.axd?a=FreeTextBox%2c+Version%3d3.1.1.34886%2c+Culture%3dneutral%2c+PublicKeyToken%3d5962a4e684a48b87&amp;r=FreeTextBoxControls.Resources.Images.Utility.spacer.gif&amp;t=632699064217187500" height="1" width="1"><br><img src="/zhugf000/admin/FtbWebResource.axd?a=FreeTextBox%2c+Version%3d3.1.1.34886%2c+Culture%3dneutral%2c+PublicKeyToken%3d5962a4e684a48b87&amp;r=FreeTextBoxControls.Resources.Images.Utility.spacer.gif&amp;t=632699064217187500" height="1" width="1"><br>应用业务框架<br><ul><li>业务框架发展策略</li><li>业务框架支持代码复用</li><li>业务框架支持CMM实施</li></ul><br><br><br><font size="2">感谢 好刚刚 同志对这篇文稿的意见，感谢 ji_cao 同志的从博弈论角度看待软件开发的思路。</font><br><img src ="http://www.blogjava.net/zhugf000/aggbug/24007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-15 12:49 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/15/24007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>变，还是不变？</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/13/23594.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Tue, 13 Dec 2005 02:05:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/13/23594.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/23594.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/13/23594.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/23594.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/23594.html</trackback:ping><description><![CDATA[<P><STRONG>变，还是不变？</STRONG></P>
<P><STRONG>变的是概念，不变的是产品<BR></STRONG>IBM 的 MQ Series 的定位从老早的 Link/Queue ，变为 MOM ，再变为 EAI ，再变为 SOA 的基础架构。MQ Series 产品的结构始终不变，但 IBM 将它用不同的概念包装起来，推向市场；客户为概念付费，而 IBM 在收获真金白银。</P>
<P><STRONG>变的是皮毛，不变的是基础<BR>变的是排列组合，不变的是基本原理</STRONG><BR>仔细考究这些概念，就会发现，概念其实只不过是对角色、数据、处理和它们之间的相互关系，将其固定化和明确化，再起个新名词。很多现在热炒的新概念，在70年代的主机上可以找到原型；代码不管是OOP 还是 AOP ，最终还是要翻译成机器码，由CPU 执行的。<BR>别被新概念给骗了，我们现在用的计算机的结构，从1950's 诺伊曼提出开始，就没有什么新变化。在可预见的将来，除非人工智能或量子计算机有什么新突破，我们还是要继续跟诺伊曼体系打交道。</P>
<P><BR><STRONG>变的是银弹，不变的是失望(?)<BR></STRONG>巨型厂商所推的概念，更多程度上是为了营销所作的吹嘘。从用户角度来看，只要开发速度足够快，运行稳定，后续支持维护升级能够跟上；到底采用什么技术，是无所谓的事情。而技术或框架之间的差别，其实也没有它们的简称之间的差别那么大。<BR></P><img src ="http://www.blogjava.net/zhugf000/aggbug/23594.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-13 10:05 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/13/23594.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式说明</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/12/23414.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Mon, 12 Dec 2005 01:16:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/12/23414.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/23414.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/12/23414.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/23414.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/23414.html</trackback:ping><description><![CDATA[
		<p align="center">
				<font color="#ff0000" size="1">Java 正则表达式的翻译文档，附带有中文部分扩展说明，源代码在<a href="/Files/zhugf000/fodian_common.rar">这里</a><br /></font>
		</p>
		<h1 align="center">正则表达式说明 
<hr width="100%" size="2" /></h1>
		<h3>目录</h3>正则表达式介绍<a href="#man_match_mode"><br />匹配模式</a><br /><a href="#man_char_class">字符子集</a><br /><a href="#man_line_terminator">行结束符</a><br /><a href="#man_group">分组和引用</a><br /><a href="#man_unicode">Unicode支持</a><br /><br /><br /><a href="#reference">正则表达式语法参考</a><br /><ol><li><a href="#ref_chars">字符</a></li><li><a href="#ref_logicopr">逻辑操作符</a></li><li><a href="#ref_backref">向后引用</a></li><li><a href="#ref_boundmeta">边界元字符</a></li><li><a href="#ref_repeatindicator">重复指示符</a></li><li><a href="#ref_char_class">字符子集</a></li><li><a href="#ref_predef_meta">预定义子集（元字符）</a></li><li>扩展子集（元字符） 
</li><li><a href="#ref_chinese_meta">扩展中文子集（元字符）</a></li><li><a href="#ref_posix_subset">POSIX字符子集（只适用于ASCII）</a></li><li><a href="#ref_unicode_category">Unicode块和分类</a><br /></li></ol><br />替换表达式<br /><a href="#man_subexp">替换表达式<br /></a><ol><li><a href="#subexp_chars">特殊字符</a></li><li><a href="#subexp_custtbl">自定义替换表</a><br /></li></ol><hr width="100%" size="2" /><h3><a name="man_match_mode"></a>匹配模式</h3>匹配模式指得是正则表达式引擎将以何种模式匹配字符串。<br /><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top">模式名称<br /></td><td valign="top">启用，禁用<br /></td><td valign="top">缺省启用<br /></td><td valign="top">说明<br /></td></tr><tr><td valign="top">UNIX_LINES<br /></td><td valign="top">(?d)启用，(?-d)禁用<br /></td><td valign="top">是<br /></td><td valign="top">启用Unix行模式。<br />在此模式下，只有 <tt>'\n'</tt>被认为是行结束符。它会影响<tt>.</tt>, <tt>^</tt>, 和 <tt>$</tt> 的行为。<br /><br /></td></tr><tr><td valign="top">CASE_INSENSITIVE<br /></td><td valign="top">(?i)启用，(?-i)禁用<br /></td><td valign="top">否<br /></td><td valign="top">启用忽略大小写模式。<br />缺省时，忽略大小写模式只会影响 ASCII字符的匹配。 而Unicode范围的忽略大小写匹配需要通过 UNICODE_CASE 标志与本标志联合使用。<br />启用此模式会影响匹配性能。<br /><br /></td></tr><tr><td valign="top">COMMENTS<br /></td><td valign="top">(?x)启用，(?-x)禁用<br /></td><td valign="top">否<br /></td><td valign="top">允许空格和注释出现在正则表达式中。<br />在此模式下，空格被忽略，以#开始的单行注释被忽略。 <br /></td></tr><tr><td valign="top">MULTILINE<br /></td><td valign="top">(?m)启用，(?-m)禁用<br /></td><td valign="top">是<br /></td><td valign="top">启用多行模式。<br />In multiline mode the expressions <tt>^</tt> and <tt>$</tt> match just after or just before, respectively, a line terminator or the end of the input sequence. By default these expressions only match at the beginning and the end of the entire input sequence. <br /><br /></td></tr><tr><td valign="top">DOTALL<br /></td><td valign="top">(?s)启用，(?-s)禁用<br /></td><td valign="top">否<br /></td><td valign="top">让.可以匹配行结束符。<br />在此模式下，元字符<tt>.</tt>可以匹配行结束符。缺省不允许如此匹配。<br /><br /><br /></td></tr><tr><td valign="top">UNICODE_CASE<br /></td><td valign="top">(?u)启用，(?-u)禁用<br /></td><td valign="top">否<br /></td><td valign="top">Enables Unicode-aware case folding.<br />When this flag is specified then case-insensitive matching, when enabled by the <code>CASE_INSENSITIVE</code> flag, is done in a manner consistent with the Unicode Standard. By default, case-insensitive matching assumes that only characters in the US-ASCII charset are being matched. 启用此模式会影响性能。<br /><br /></td></tr><tr><td valign="top">CANON_EQ<br /></td><td valign="top">(?c)启用，(?-c)禁用<br /></td><td valign="top">否<br /></td><td valign="top">Enables canonical equivalence.<br />When this flag is specified then two characters will be considered to match if, and only if, their full canonical decompositions match. The expression <tt>"a\u030A"</tt>, for example, will match the string <tt>"?"</tt> when this flag is specified. By default, matching does not take canonical equivalence into account. <br />启用此模式会影响性能。<br /><br /></td></tr></tbody></table><br /><br /><h3><a name="man_char_class"></a>字符子集</h3>字符子集可以含有别的字符子集，并且可以通过联合操作符（缺省）和交集操作符（&amp;&amp;）实现组合。联合操作符表示某个子集匹配它的子子集所匹配的任意字符。交集操作符表明某个字符子集只匹配它的子子集都匹配的字符。<br />字符子集所能够有的操作符的优先级如下，从高到低：<br /><ol><li>转义符\x 
</li><li>成组符 [...] 
</li><li>区间符 a-z 
</li><li>联合符 [a-e][i-u] 
</li><li>交集符 [a-z&amp;&amp;[aeiou]]</li></ol>注意：在字符子集[]内部的语法根本不同于正则表达式其它部分中的语法。例如，在字符子集内部，正则表达式 . 失去了它原有的含义，而是成了一个匹配.的元字符。 <br /><br /><h3><a name="man_line_terminator"></a>行结束符</h3>行结束符是一个或两个字符序列，用以表明输入字符序列中一行的结束。下面的字符被认为是行结束符：<br /><ul><li>一个换行符('\n')。 
</li><li>一个回车符加上一个换行符("\r\n")。 
</li><li>一个单独的回车符('\r')。 
</li><li>代表下一行的字符('\u0085')。 
</li><li>行分隔符('\u2028')，Unicode中被定义。 
</li><li>一个分段符('\u2029)，Unicode中被定义。</li></ul>如果 UNIX_LINES 模式被启用，则只有换行符被认为是行结束符。<br />如果 MULTILINE 模式被启用，。<br /><br /><h3><a name="man_group"></a>分组和引用</h3>字符分组以它们的左括号的出现顺序来排序。例如在表达式((A)(B(C)))，有四个分组：<br /><ol><li>((A)(B(C))) 
</li><li>(A) 
</li><li>(B(C)) 
</li><li>(C)</li></ol>第0组永远表示表达式本身。<br />分组采用这样的命名方式，是因为，在一次匹配过程中，正则表达式会被匹配多次。以前的匹配子序列有可能在将来被使用；或者在匹配结束时，程序有可能需要重新获得所有匹配的子字符序列。<br />对于正则表达式中的某个分组而言，永远只保留最后匹配的字符序列。如果对某个分组匹配尝试失败，则会保留上次匹配成功的字符序列。例如，对于正则表达式(a(b)?)+而言，字符序列"aba"，将会让分组2匹配的字符序列为"b"。<br />以(?开始的分组，将不会计入分组数目，也不会被后续匹配所引用。<br /><br /><h3><a name="man_unicode"></a>Unicode支持</h3>本正则表达式匹配引擎的实现遵循了《<a href="http://www.unicode.org/unicode/reports/tr18/">Unicode技术报告：Unicode正则表达式指南</a>》，实现了该指南的第二层所需的功能，但是在细微处有一些简单语法修改。<br />Unicode块(Block)和分类(Category)通过\p和\P通配苻表示。\p{<b><i>prop</i></b>}匹配含有<b><i>prop</i></b>的输入序列，而\P{<b><i>prop</i></b>}匹配不含有<b><i>prop</i></b>的输入序列。Unicode块通过前缀<tt>In</tt>表示，如\p{InMongolian}。Unicode分类通过可选的前缀Is表示，因此\p{L}和\p{IsL}都代表Unicode分类 letters。Unicode块和分类都可以在正则表达式子集外部和内部使用。<br />目前支持的Unicode块和分类是《<a href="http://www.unicode.org/unicode/standard/standard.html">Unicode标准，第三版</a>》中所指定的块和分类。 Unicode块名称在《<a href="http://www.unicode.org/Public/3.0-Update/UnicodeCharacterDatabase-3.0.0.html">Unicode 字符数据库</a>》的第14章被定义，文件名称叫<a href="http://www.unicode.org/Public/3.0-Update/Blocks-3.txt">Blocks-3.txt</a>，但是名称中的空格被去掉了。例如"Basic Latin"成了"BasicLatin"。无论是标准化的还是非标准化的分类，都在该标准的第88页的第4-5表中被全部定义。<br /><br /><h3><a name="man_compare_perl5"></a>与Perl 5正则表达式语法对比 </h3>[TBD]<br /><br /><hr width="100%" size="2" /><h2><a name="reference"></a>正则表达式参考</h2><br /><hr width="100%" size="2" /><h3><a name="ref_chars"></a>字符</h3><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top" width="30%">正则表达式字符串<br /></td><td valign="top">匹配的字符串<br /></td></tr><tr><td valign="top" width="30%">X<br /></td><td valign="top">字符X，包括 CJK ExtB 区汉字<br /></td></tr><tr><td valign="top" width="30%">\\<br /></td><td valign="top">反斜杠\<br /></td></tr><tr><td valign="top" width="30%">\0<b><i>n</i></b></td><td valign="top">八进制0<b><i>n</i></b>代表的字符(0&lt;=n&lt;=7)<br /></td></tr><tr><td valign="top" width="30%">\0<b><i>nn</i></b><br /></td><td valign="top">八进制0<b><i>nn</i></b>代表的字符(0&lt;=n&lt;=7)<br /></td></tr><tr><td valign="top" width="30%">\0<b><i>mnn</i></b><br /></td><td valign="top">八进制0<b><i>mnn</i></b>代表的字符(0&lt;=m&lt;=3,0&lt;=n&lt;=7)<br /></td></tr><tr><td valign="top" width="30%">\x<b><i>hh</i></b><br /></td><td valign="top">十六进制 0x<b><i>hh</i></b>所代表的字符<br /></td></tr><tr><td valign="top" width="30%">\u<b><i>hhhh</i></b><br /></td><td valign="top">十六进制 0x<b><i>hhhh</i></b>所代表的字符。<font color="#ff0000">注意</font>，目前尚不支持CJK ExtB区汉字。<br /></td></tr><tr><td valign="top" width="30%">\t<br /></td><td valign="top">制表符('\u0009')<br /></td></tr><tr><td valign="top">\n<br /></td><td valign="top">换行('\u000A')<br /></td></tr><tr><td valign="top">\r<br /></td><td valign="top">回车('\u000D')<br /></td></tr><tr><td valign="top">\a<br /></td><td valign="top">响铃符('\u0007')<br /></td></tr><tr><td valign="top">\e<br /></td><td valign="top">取消符Escape('\001B')<br /></td></tr><tr><td valign="top">\c<i><b>x</b></i><br /></td><td valign="top"><i><b>x</b></i>所代表的控制字符<br /></td></tr></tbody></table><br /><h3><a name="ref_logicopr"></a>逻辑操作符</h3><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top" width="30%">正则表达式字符串<br /></td><td valign="top">匹配的字符串<br /></td></tr><tr><td valign="top" width="30%"><i>XY</i><br /></td><td valign="top"><i>X</i>后面跟随<i>Y</i><br /></td></tr><tr><td valign="top" width="30%"><i>X</i>|<i>Y</i><br /></td><td valign="top"><i>X</i>或者<i>Y</i><br /></td></tr><tr><td valign="top" width="30%">(<i>X</i>)<br /></td><td valign="top"><i>X</i>作为分组表达式<br /></td></tr></tbody></table><br /><h3><a name="ref_backref"></a>向后引用</h3><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top" width="30%">正则表达式字符串<br /></td><td valign="top">匹配的字符串<br /></td></tr><tr><td valign="top" width="30%">\<b>n</b><br /></td><td valign="top">第<b>n</b>个匹配的分组<br /></td></tr></tbody></table><br /><h3><a name="ref_boundmeta"></a>边界元字符</h3><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top" width="30%">边界字符<br /></td><td valign="top">匹配的字符串<br /></td></tr><tr><td valign="top" width="30%">^<br /></td><td valign="top">行首<br /></td></tr><tr><td valign="top" width="30%">$<br /></td><td valign="top">行末<br /></td></tr><tr><td valign="top" width="30%">\b </td><td valign="top">字符边界<br /></td></tr><tr><td valign="top" width="30%">\B<br /></td><td valign="top">非字符边界<br /></td></tr><tr><td valign="top" width="30%">\A<br /></td><td valign="top">输入流的开始<br /></td></tr><tr><td valign="top" width="30%">\G<br /></td><td valign="top">上次匹配的结束处<br /></td></tr><tr><td valign="top" width="30%">\Z<br /></td><td valign="top">输入流的结束，或者是最后一个行结束符，参见<a href="file:///D:/source/jtextpro/src/dist/jtextpro/docs/regexp.html#man_line_terminator">行结束符</a>。<br /></td></tr><tr><td valign="top" width="30%">\z<br /></td><td valign="top">输入流的结束<br /></td></tr></tbody></table><br /><h3><a name="ref_repeatindicator"></a>重复指示符</h3><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top" width="30%">正则表达式字符串<br /></td><td valign="top">匹配的字符串<br /></td></tr><tr><td valign="top" width="30%"><b>X</b>?<br /></td><td valign="top"><b>X</b>重复一次，或者不重复<br /></td></tr><tr><td valign="top" width="30%"><b>X</b>*<br /></td><td valign="top"><b>X</b>重复0次或多次<br /></td></tr><tr><td valign="top" width="30%"><b>X</b>+ <br /></td><td valign="top"><b>X</b>重复1次或多次<br /></td></tr><tr><td valign="top" width="30%"><b>X</b>{n}<br /></td><td valign="top"><b>X</b>重复n次，不多也不少。<br /></td></tr><tr><td valign="top" width="30%"><b>X</b>{n,}<br /></td><td valign="top"><b>X</b>至少重复n次<br /></td></tr><tr><td valign="top" width="30%"><b>X</b>{n,m}<br /></td><td valign="top"><b>X</b>至少重复n次，至多重复m次。<br /></td></tr></tbody></table>注：<b>X</b>{n,m}、?、*、+方式可以联合使用。<br /><br /><h3><a name="ref_char_class"></a>字符子集</h3><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top" width="30%">正则表达式字符串子集<br /></td><td valign="top" width="50%">匹配的字符串<br /></td><td valign="top" align="left" width="20%">组合方式<br /></td></tr><tr><td valign="top" width="30%">[abc]<br /></td><td valign="top" width="60%">字符a,b或c，包括 CJK ExtB 区汉字<br /></td><td valign="top" align="left" width="20%">简单子集<br /></td></tr><tr><td valign="top" width="30%">[^abc]<br /></td><td valign="top" width="60%">任意非a,b或c的字符。<br /></td><td valign="top" align="left" width="20%">排除<br /></td></tr><tr><td valign="top" width="30%">[a-zA-Z] </td><td valign="top" width="60%">从a到z，或者A到Z，包含a,z,A,Z。<br /></td><td valign="top" align="left" width="20%">区间<br /></td></tr><tr><td valign="top" width="30%">[a-d[m-p]]<br /></td><td valign="top" width="60%">从a到d，或者m到p，等于[a-dm-p]。<br /></td><td valign="top" align="left" width="20%">联合<br /></td></tr><tr><td valign="top" width="30%">[a-z&amp;&amp;[def]]<br /></td><td valign="top" width="60%">d,e或者f。<br /></td><td valign="top" align="left" width="20%">交集<br /></td></tr><tr><td valign="top">[a-z&amp;&amp;[^bc]]<br /></td><td valign="top" width="60%">从a到z，除了b和c，等于[ad-z]<br /></td><td valign="top" align="left" width="20%">扣除<br /></td></tr><tr><td valign="top">[a-z&amp;&amp;[^m-p]]<br /></td><td valign="top">从a到z，并且不包括从m到p，等于[a-lq-z]<br /></td><td valign="top">扣除<br /></td></tr></tbody></table><br /><h3><a name="ref_predef_meta"></a>预定义子集（元字符）</h3><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top" width="30%">边界字符<br /></td><td valign="top">匹配的字符串<br /></td></tr><tr><td valign="top" width="30%">.<br /></td><td valign="top">任意字符，可能匹配行结束符。<br /></td></tr><tr><td valign="top" width="30%">\d<br /></td><td valign="top">数字[0-9]<br /></td></tr><tr><td valign="top" width="30%">\D </td><td valign="top">非数字[^0-9]<br /></td></tr><tr><td valign="top" width="30%">\s<br /></td><td valign="top">空白符[ \t\n\x0B\f\r]<br /></td></tr><tr><td valign="top" width="30%">\S<br /></td><td valign="top">非空白符[^\s]<br /></td></tr><tr><td valign="top" width="30%">\w<br /></td><td valign="top">单词符，包含有字母和数字[a-zA-Z_0-9]<br /></td></tr><tr><td valign="top" width="30%">\W<br /></td><td valign="top">非单词符，不包含有字母和数字。<br /></td></tr></tbody></table><br /><h3>扩展子集（元字符）</h3><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top" width="30%">正则表达式字符串<br /></td><td valign="top">匹配的字符串<br /></td></tr><tr><td valign="top" width="30%"><br /></td><td valign="top"><br /></td></tr></tbody></table><br /><br /><h3><a name="ref_chinese_meta"></a>扩展中文子集（元字符）</h3><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top">名称<br /></td><td valign="top">块名称（\p{InXXX}）<br /></td><td valign="top">简化通配符<br /></td><td valign="top">标准Unicode块，或者汉字列表<br /></td></tr><tr><td valign="top">任意双字节字符（汉字或全角符号）<br /></td><td valign="top">\p{InQuqnJiao}<br /></td><td valign="top">\E<br /></td><td valign="top">任意由GBK表示的汉字，不包括GB18030扩展部分，<br />以及CJK ExtB区的汉字。<br /></td></tr><tr><td valign="top">任意单字节字符<br /></td><td valign="top">\p{InFQuanJiao}<br /></td><td valign="top">\~E<br /></td><td valign="top">任意单字节字符。<br /></td></tr><tr><td valign="top">任意全角ASCII字符<br /></td><td valign="top">\p{InQJAscii}<br /></td><td valign="top">\H<br /></td><td valign="top">标准HalfwidthandFullwidthForms块<br /></td></tr><tr><td valign="top">任意收录在BIG5码集中的双字节字符<br /></td><td valign="top">\p{InBig5}<br /></td><td valign="top">\I<br /></td><td valign="top">Big5可编码双字节字符<br /></td></tr><tr><td valign="top">匹配未收录在BIG5码集中的双字节字符</td><td valign="top">\p{InFBig5}<br /></td><td valign="top">\~I<br /></td><td valign="top">非Big5可编码双字节字符<br /></td></tr><tr><td valign="top">匹配任意汉字(不包括符号)<br /></td><td valign="top">\p{InHanziOrCJKExtB}<br /></td><td valign="top">\X<br /></td><td valign="top">任意汉字，包括GB18030扩展部分。<br /></td></tr><tr><td valign="top">匹配任意汉字(不包括符号)<br /></td><td valign="top">\p{InHanzi}<br /></td><td valign="top">\M<br /></td><td valign="top">任意汉字，不包括GB18030扩展部分。<br /></td></tr><tr><td valign="top">匹配非汉字的双字节字符<br /></td><td valign="top">\p{InFHanzi}<br /></td><td valign="top">\~M<br /></td><td valign="top">任意非汉字的双字节字符，<br />包括GB18030扩展部分。<br /></td></tr><tr><td valign="top">地支字符<br /></td><td valign="top">\p{InDiZhi}<br /></td><td valign="top">\U<br /></td><td valign="top">子丑寅卯辰巳午未申酉戌亥<br /></td></tr><tr><td valign="top">匹配收录在GB码集中的双字节字符<br /></td><td valign="top">\p{InGB}<br /></td><td valign="top">\g<br /></td><td valign="top">收录在GB码集中的双字节字符，<br />不包括GB18030扩展部分。<br /></td></tr><tr><td valign="top">匹配非收录在GB码集中的双字节字符<br /></td><td valign="top">\p{InFGB}<br /></td><td valign="top">\~g<br /></td><td valign="top">未收录在GB码集中的双字节字符，<br />不包括GB18030扩展部分。<br /></td></tr><tr><td valign="top">匹配收录在GBK码集中的双字节字符<br /></td><td valign="top">\p{InGBK}<br /></td><td valign="top">\h<br /></td><td valign="top">收录在GBK码集中的双字节字符，<br />不包括GB18030扩展部分。<br /></td></tr><tr><td valign="top">匹配非收录在GBK码集中的双字节字符<br /></td><td valign="top">\p{InFGBK}<br /></td><td valign="top">\~h<br /></td><td valign="top">未收录在GBK码集中的双字节字符，<br />不包括GB18030扩展部分。<br /></td></tr><tr><td valign="top">大写希腊字母<br /></td><td valign="top">\p{InDaXila}<br /></td><td valign="top">\K<br /></td><td valign="top">ΑΒΓΔΕΖΗΘΙΚΛΜΝ<br />ΞΟΠΡΣΤΥΦΧΨΩ<br /></td></tr><tr><td valign="top">日文片假名<br /></td><td valign="top">\p{InPianJia}<br /></td><td valign="top">\j<br /></td><td valign="top">标准Katakana块<br /></td></tr><tr><td valign="top">日文平假名<br /></td><td valign="top">\p{InPingJia}<br /></td><td valign="top">\J<br /></td><td valign="top">标准Hiragana块<br /></td></tr><tr><td valign="top">小写希腊字母<br /></td><td valign="top">\p{InXiaoXila}<br /></td><td valign="top">\k<br /></td><td valign="top">αβγδεζηθικλμν<br />ξοπρστυφχψω<br /></td></tr><tr><td valign="top">数学符号<br /></td><td valign="top">\p{InMathe}<br /></td><td valign="top">\m<br /></td><td valign="top">±×÷∶∧∨∑∏∪∩∈∷√⊥∥∠⌒⊙<br />∫∮≡≌≈∽∝≠≮≯≤≥∞∵∴<br /></td></tr><tr><td valign="top">中文数字<br /></td><td valign="top">\p{InCnDigit}<br /></td><td valign="top">\i<br /></td><td valign="top">〇一二三四五六七八九十百千万亿兆吉京<br /></td></tr><tr><td valign="top">大写中文数字<br /></td><td valign="top">\p{InDaCnDigit}<br /></td><td valign="top">\N<br /></td><td valign="top">零壹贰叁肆伍陆柒捌玖拾佰仟萬亿兆吉京<br /></td></tr><tr><td valign="top">全角标点符号<br /></td><td valign="top">\p{InQJBiaoDian}<br /></td><td valign="top">\o<br /></td><td valign="top">、。·ˉˇ¨〃々—～‖…‘’“”〔〕<br />〈〉《》「」『』〖〗【】！＂＇（），<br />－．：；＜＝＞？［］｛｜｝｀﹉﹊﹋﹌﹍﹎﹏﹐﹑﹒﹔﹕﹖﹗﹙﹚<br />﹛﹜﹝﹞︵︶︹︺︿﹀︽︾﹁﹂﹃﹄<br />︻︼︷︸︱︳︴<br /></td></tr><tr><td valign="top">小写俄文字母<br /></td><td valign="top">\p{InXiaoEWen}<br /></td><td valign="top">\l<br /></td><td valign="top">абвгдеёжзийклмн<br />опрстуфхцчшщъыьэюя<br /></td></tr><tr><td valign="top">大写俄文字母<br /></td><td valign="top">\p{InDaEWen}<br /></td><td valign="top">\R<br /></td><td valign="top">АБВГДЕЁЖЗИЙКЛМНО<br />ПРСТУФХЦЧШЩЪЫЬЭЮЯ<br /></td></tr><tr><td valign="top">中文序号<br /></td><td valign="top">\p{InCnSN}<br /></td><td valign="top">\q<br /></td><td valign="top">ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ<br />ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹ<br />再加上Unicode标准EnclosedAlphanumerics块<br /></td></tr><tr><td valign="top">天干字符<br /></td><td valign="top">\p{InTianGan}<br /></td><td valign="top">\T<br /></td><td valign="top">甲乙丙丁戊己庚辛壬癸<br /></td></tr><tr><td valign="top">竖排标点符号<br /></td><td valign="top">\p{InSPBiaoDian}<br /></td><td valign="top">\V<br /></td><td valign="top">︵︶︹︺︿﹀︽︾﹁﹂﹃﹄︻︼︷︸︱︳︴<br /></td></tr><tr><td valign="top">拼音字符<br /></td><td valign="top">\p{InPinyin}<br /></td><td valign="top">\y<br /></td><td valign="top">āáǎàēéěèīíǐìōóǒòūúǔùǖǘǚǜüêɑńňɡ<br />GBK -&gt; 0xA8A1- 0xA8C0<br />只是Unicode标准LatinExtended-A块的一部分。<br /></td></tr><tr><td valign="top">注音字符<br /></td><td valign="top">\p{InZhuyin}<br /></td><td valign="top">\Y<br /></td><td valign="top">标准Bopomofo块<br /></td></tr><tr><td valign="top">制表字符<br /></td><td valign="top">\p{InZhiBiao}<br /></td><td valign="top">\C<br /></td><td valign="top">标准BoxDrawing块。<br />经检查发现 textpro 的算法含有部分非标<br />准Unicode制表符：“∟∣≒≦≧⊿═”。<br /></td></tr></tbody></table><br /><h3><a name="ref_posix_subset"></a>POSIX字符子集（只适用于ASCII）</h3><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top" width="30%">正则表达式字符串<br /></td><td valign="top">匹配的字符串<br /></td></tr><tr><td valign="top" width="30%">\p{Lower}<br /></td><td valign="top">小写字母[a-z]<br /></td></tr><tr><td valign="top" width="30%">\p{Upper}<br /></td><td valign="top">大写字母[A-Z]<br /></td></tr><tr><td valign="top" width="30%">\p{ASCII}<br /></td><td valign="top">所有的ASCII字符[\x00-\x7F]<br /></td></tr><tr><td valign="top" width="30%">\p{Alpha}<br /></td><td valign="top">大小写字母[\p{Lower}\p{Upper}]<br /></td></tr><tr><td valign="top" width="30%">\p{Digit}<br /></td><td valign="top">数字[0-9]<br /></td></tr><tr><td valign="top" width="30%">\p{Alnum}<br /></td><td valign="top">字母数字符，包含大小写字母和数字[\p{Alpha}\p{Digit}]<br /></td></tr><tr><td valign="top" width="30%">\p{Punct}<br /></td><td valign="top">标点符号，!"#$%&amp;'()*+,-./:;&lt;=&gt;?@[\]^_`{|}~之一。<br /></td></tr><tr><td valign="top" width="30%">\p{Graph}<br /></td><td valign="top">可显示字符[\p{Alnum}\p{Punct}]<br /></td></tr><tr><td valign="top">\p{Print}<br /></td><td valign="top">可打印字符[\p{Graph}]<br /></td></tr><tr><td valign="top">\p{Blank}<br /></td><td valign="top">空格或者制表符[ \t]<br /></td></tr><tr><td valign="top">\p{Cntrl}<br /></td><td valign="top">控制字符[\x00-\x1F\x7F<br /></td></tr><tr><td valign="top">\p{XDigit}<br /></td><td valign="top">十六进制数字[0-9a-fA-F]<br /></td></tr><tr><td valign="top">\p{Space}<br /></td><td valign="top">空白符[ \t\n\x0B\f\r]<br /></td></tr></tbody></table><br /><h3><a name="ref_unicode_category"></a>Unicode块和分类</h3><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top">块<br /></td><td valign="top">中文名称（摘自Word XP）<br /></td><td valign="top">代码区域<br /></td></tr><tr><td valign="top">BasicLatin<br /></td><td valign="top">基本拉丁语<br /></td><td valign="top">\u0000-\u007F<br /></td></tr><tr><td valign="top">Latin-1Supplement<br /></td><td valign="top">拉丁语-1<br /></td><td valign="top">\u0080-\u00FF<br /></td></tr><tr><td valign="top">LatinExtended-A<br /></td><td valign="top">拉丁语扩充-A<br /></td><td valign="top">\u0100-\u017F<br /></td></tr><tr><td valign="top">LatinExtended-Bound<br /></td><td valign="top">拉丁语扩充-B<br /></td><td valign="top">\u0180-\u024F<br /></td></tr><tr><td valign="top">IPAExtensions<br /></td><td valign="top">国际音标扩充<br /></td><td valign="top">\u0250-\u02AF<br /></td></tr><tr><td valign="top">SpacingModifierLetters<br /></td><td valign="top">进格的修饰字符<br /></td><td valign="top">\u02B0-\u02FF<br /></td></tr><tr><td valign="top">CombiningDiacriticalMarks<br /></td><td valign="top">组合用发音符<br /></td><td valign="top">\u0300-\u036F<br /></td></tr><tr><td valign="top">Greek<br /></td><td valign="top">基本希腊语<br /></td><td valign="top">\u0370-\u03FF<br /></td></tr><tr><td valign="top">Cyrillic<br /></td><td valign="top">西里尔语<br /></td><td valign="top">\u0400-\u04FF<br /></td></tr><tr><td valign="top">Armenian<br /></td><td valign="top"><br /></td><td valign="top">\u0530-\u058F<br /></td></tr><tr><td valign="top">Hebrew<br /></td><td valign="top"><br /></td><td valign="top">\u0590-\u05FF<br /></td></tr><tr><td valign="top">Arabic<br /></td><td valign="top"><br /></td><td valign="top">\u0600-\u06FF<br /></td></tr><tr><td valign="top">Syriac<br /></td><td valign="top"><br /></td><td valign="top">\u0700-\u074F<br /></td></tr><tr><td valign="top">Thaana<br /></td><td valign="top"><br /></td><td valign="top">\u0780-\u07BF<br /></td></tr><tr><td valign="top">Devanagari<br /></td><td valign="top"><br /></td><td valign="top">\u0900-\u097F<br /></td></tr><tr><td valign="top">Bengali<br /></td><td valign="top"><br /></td><td valign="top">\u0980-\u09FF<br /></td></tr><tr><td valign="top">Gurmukhi<br /></td><td valign="top"><br /></td><td valign="top">\u0A00-\u0A7F<br /></td></tr><tr><td valign="top">Gujarati<br /></td><td valign="top"><br /></td><td valign="top">\u0A80-\u0AFF<br /></td></tr><tr><td valign="top">Oriya<br /></td><td valign="top"><br /></td><td valign="top">\u0B00-\u0B7F<br /></td></tr><tr><td valign="top">Tamil<br /></td><td valign="top"><br /></td><td valign="top">\u0B80-\u0BFF<br /></td></tr><tr><td valign="top">Telugu<br /></td><td valign="top"><br /></td><td valign="top">\u0C00-\u0C7F<br /></td></tr><tr><td valign="top">Kannada<br /></td><td valign="top"><br /></td><td valign="top">\u0C80-\u0CFF<br /></td></tr><tr><td valign="top">Malayalam<br /></td><td valign="top"><br /></td><td valign="top">\u0D00-\u0D7F<br /></td></tr><tr><td valign="top">Sinhala<br /></td><td valign="top"><br /></td><td valign="top">\u0D800-\uDFF<br /></td></tr><tr><td valign="top">Thai<br /></td><td valign="top"><br /></td><td valign="top">\u0E00-\u0E7F<br /></td></tr><tr><td valign="top">Lao<br /></td><td valign="top"><br /></td><td valign="top">\u0E80-\u0EFF<br /></td></tr><tr><td valign="top">Tibetan<br /></td><td valign="top">藏语<br /></td><td valign="top">\u0F00-\u0FFF<br /></td></tr><tr><td valign="top">Myanmar<br /></td><td valign="top"><br /></td><td valign="top">\u1000-\u109F<br /></td></tr><tr><td valign="top">Georgian<br /></td><td valign="top"><br /></td><td valign="top">\u10A0-\u10FF<br /></td></tr><tr><td valign="top">HangulJamo<br /></td><td valign="top"><br /></td><td valign="top">\u1100-\u11FF<br /></td></tr><tr><td valign="top">Ethiopic<br /></td><td valign="top"><br /></td><td valign="top">\u1200-\u137F<br /></td></tr><tr><td valign="top">Cherokee<br /></td><td valign="top"><br /></td><td valign="top">\u13A0-\u13FF<br /></td></tr><tr><td valign="top">UnifiedCanadianAboriginalSyllabics<br /></td><td valign="top"><br /></td><td valign="top">\u1400-\u167F<br /></td></tr><tr><td valign="top">Ogham<br /></td><td valign="top"><br /></td><td valign="top">\u1680-\u169F<br /></td></tr><tr><td valign="top">Runic<br /></td><td valign="top"><br /></td><td valign="top">\u16A0-\u16FF<br /></td></tr><tr><td valign="top">Khmer<br /></td><td valign="top"><br /></td><td valign="top">\u1780-\u17FF<br /></td></tr><tr><td valign="top">Mongolian<br /></td><td valign="top">蒙古语<br /></td><td valign="top">\u1800-\u18AF<br /></td></tr><tr><td valign="top">LatinExtendedAdditional<br /></td><td valign="top"><br /></td><td valign="top">\u1E00-\u1EFF<br /></td></tr><tr><td valign="top">GreekExtended<br /></td><td valign="top"><br /></td><td valign="top">\u1F00-\u1FFF<br /></td></tr><tr><td valign="top">GeneralPunctuation<br /></td><td valign="top">广义标点<br /></td><td valign="top">\u2000-\u206F<br /></td></tr><tr><td valign="top">SuperscriptsandSubscripts<br /></td><td valign="top"><br /></td><td valign="top">\u2070-\u209F<br /></td></tr><tr><td valign="top">CurrencySymbols<br /></td><td valign="top">货币符号<br /></td><td valign="top">\u20A0-\u20CF<br /></td></tr><tr><td valign="top">CombiningMarksforSymbols<br /></td><td valign="top"><br /></td><td valign="top">\u20D0-\u20FF<br /></td></tr><tr><td valign="top">LetterlikeSymbols<br /></td><td valign="top">类似字母的符号<br /></td><td valign="top">\u2100-\u214F<br /></td></tr><tr><td valign="top">NumberForms<br /></td><td valign="top">数字形式<br /></td><td valign="top">\u2150-\u218F<br /></td></tr><tr><td valign="top">Arrows<br /></td><td valign="top">箭头<br /></td><td valign="top">\u2190-\u21FF<br /></td></tr><tr><td valign="top">MathematicalOperators<br /></td><td valign="top">数学运算符<br /></td><td valign="top">\u2200-\u22FF<br /></td></tr><tr><td valign="top">MiscellaneousTechnical<br /></td><td valign="top">零杂技术用符号<br /></td><td valign="top">\u2300-\u23FF<br /></td></tr><tr><td valign="top">ControlPictures<br /></td><td valign="top"><br /></td><td valign="top">\u2400-\u243F<br /></td></tr><tr><td valign="top">OpticalCharacterRecognition<br /></td><td valign="top"><br /></td><td valign="top">\u2440-\u245F<br /></td></tr><tr><td valign="top">EnclosedAlphanumerics<br /></td><td valign="top">带括号的字母数字<br /></td><td valign="top">\u2460-\u24FF<br /></td></tr><tr><td valign="top">BoxDrawing<br /></td><td valign="top">制表符<br /></td><td valign="top">\u2500-\u257F<br /></td></tr><tr><td valign="top">BlockElements<br /></td><td valign="top">方块图形<br /></td><td valign="top">\u2580-\u259F<br /></td></tr><tr><td valign="top">GeometricShapes<br /></td><td valign="top">几何图形<br /></td><td valign="top">\u25A0-\u25FF<br /></td></tr><tr><td valign="top">MiscellaneousSymbols<br /></td><td valign="top">零杂丁贝符（示意符等）<br /></td><td valign="top">\u2600-\u26FF<br /></td></tr><tr><td valign="top">Dingbats<br /></td><td valign="top"><br /></td><td valign="top">\u2700-\u27BF<br /></td></tr><tr><td valign="top">BraillePatterns<br /></td><td valign="top"><br /></td><td valign="top">\u2800-\u28FF<br /></td></tr><tr><td valign="top">CJKRadicalsSupplement<br /></td><td valign="top"><br /></td><td valign="top">\u2E80-\u2EFF<br /></td></tr><tr><td valign="top">KangxiRadicals<br /></td><td valign="top"><br /></td><td valign="top">\u2F00-\u2FDF<br /></td></tr><tr><td valign="top">IdeographicDescriptionCharacters<br /></td><td valign="top"><br /></td><td valign="top">\u2FF0-\u2FFF<br /></td></tr><tr><td valign="top">CJKSymbolsandPunctuation<br /></td><td valign="top">CJK符号和标点<br /></td><td valign="top">\u3000-\u303F<br /></td></tr><tr><td valign="top">Hiragana<br /></td><td valign="top">平假名<br /></td><td valign="top">\u3040-\u309F<br /></td></tr><tr><td valign="top">Katakana<br /></td><td valign="top">片假名<br /></td><td valign="top">\u30A0-\u30FF<br /></td></tr><tr><td valign="top">Bopomofo<br /></td><td valign="top">注音<br /></td><td valign="top">\u3100-\u312F<br /></td></tr><tr><td valign="top">HangulCompatibilityJamo<br /></td><td valign="top"><br /></td><td valign="top">\u3130-\u318F<br /></td></tr><tr><td valign="top">Kanbun<br /></td><td valign="top"><br /></td><td valign="top">\u3190-\u319F<br /></td></tr><tr><td valign="top">BopomofoExtended<br /></td><td valign="top">扩展注音<br /></td><td valign="top">\u31A0-\u31BF<br /></td></tr><tr><td valign="top">EnclosedCJKLettersandMonths<br /></td><td valign="top">带括号的CJK字母及月份<br /></td><td valign="top">\u3200-\u32FF<br /></td></tr><tr><td valign="top">CJKCompatibility<br /></td><td valign="top">CJK兼容字符<br /></td><td valign="top">\u3300-\u33FF <br /></td></tr><tr><td valign="top">CJKUnifiedIdeographsExtensionA<br /></td><td valign="top">CJK统一汉字扩展-A<br /></td><td valign="top">\u3400-\u4dBF<br /></td></tr><tr><td valign="top">CJKUnifiedIdeographs<br /></td><td valign="top">CJK统一汉字<br /></td><td valign="top">\u4E00-\u9fAF<br /></td></tr><tr><td valign="top">YiSyllables<br /></td><td valign="top"><br /></td><td valign="top">\uA000-\uA48F<br /></td></tr><tr><td valign="top">YiRadicals<br /></td><td valign="top"><br /></td><td valign="top">\uA490-\uA4CF<br /></td></tr><tr><td valign="top">HangulSyllables<br /></td><td valign="top"><br /></td><td valign="top">\uAC00-\uD7A3<br /></td></tr><tr><td valign="top">HighSurrogates<br /></td><td valign="top"><br /></td><td valign="top">\uD800-\uDB7F<br /></td></tr><tr><td valign="top">HighPrivateUseSurrogates<br /></td><td valign="top"><br /></td><td valign="top">\uDB80-\uDBFF<br /></td></tr><tr><td valign="top">LowSurrogates<br /></td><td valign="top"><br /></td><td valign="top">\uDC00-\uDFFF<br /></td></tr><tr><td valign="top">PrivateUse<br /></td><td valign="top">专用区<br /></td><td valign="top">\uE000-\uF8FF<br /></td></tr><tr><td valign="top">CJKCompatibilityIdeographs<br /></td><td valign="top">CJK兼容汉字<br /></td><td valign="top">\uF900-\uFAFF<br /></td></tr><tr><td valign="top">AlphabeticPresentationForms<br /></td><td valign="top"><br /></td><td valign="top">\uFB00-\uFB4F<br /></td></tr><tr><td valign="top">ArabicPresentationForms-A<br /></td><td valign="top"><br /></td><td valign="top">\uFB50-\uFDFF<br /></td></tr><tr><td valign="top">CombiningHalfMarks<br /></td><td valign="top"><br /></td><td valign="top">\uFE20-\uFE2F<br /></td></tr><tr><td valign="top">CJKCompatibilityForms<br /></td><td valign="top">CJK兼容形式<br /></td><td valign="top">\uFE30-\uFE4F<br /></td></tr><tr><td valign="top">SmallFormVariants<br /></td><td valign="top">小写变体<br /></td><td valign="top">\uFE50-\uFE6F<br /></td></tr><tr><td valign="top">ArabicPresentationForms-Bound<br /></td><td valign="top"><br /></td><td valign="top">\uFE70-\ufeFF<br /></td></tr><tr><td valign="top">Specials<br /></td><td valign="top"><br /></td><td valign="top">\uFFF0-\uFFFF<br /></td></tr><tr><td valign="top">HalfwidthandFullwidthForms<br /></td><td valign="top">半形及全形字符<br /></td><td valign="top">\uFF00-\uFFEF<br /></td></tr></tbody></table><br /><br /><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top">分类<br /></td><td valign="top">全称<br /></td><td valign="top">说明<br /></td></tr><tr><td valign="top">Cn<br /></td><td valign="top"><br /></td><td valign="top">UNASSIGNED<br /></td></tr><tr><td valign="top">Lu<br /></td><td valign="top"><br /></td><td valign="top">UPPERCASE_LETTER<br /></td></tr><tr><td valign="top">Ll<br /></td><td valign="top"><br /></td><td valign="top">LOWERCASE_LETTER<br /></td></tr><tr><td valign="top">Lt<br /></td><td valign="top"><br /></td><td valign="top">TITLECASE_LETTER<br /></td></tr><tr><td valign="top">Lm<br /></td><td valign="top"><br /></td><td valign="top">MODIFIER_LETTER<br /></td></tr><tr><td valign="top">Lo<br /></td><td valign="top"><br /></td><td valign="top">OTHER_LETTER<br /></td></tr><tr><td valign="top">Mn<br /></td><td valign="top"><br /></td><td valign="top">NON_SPACING_MARK<br /></td></tr><tr><td valign="top">Me<br /></td><td valign="top"><br /></td><td valign="top">ENCLOSING_MARK<br /></td></tr><tr><td valign="top">Mc<br /></td><td valign="top"><br /></td><td valign="top">COMBINING_SPACING_MARK<br /></td></tr><tr><td valign="top">Nd<br /></td><td valign="top"><br /></td><td valign="top">DECIMAL_DIGIT_NUMBER<br /></td></tr><tr><td valign="top">Nl<br /></td><td valign="top"><br /></td><td valign="top">LETTER_NUMBER<br /></td></tr><tr><td valign="top">No<br /></td><td valign="top"><br /></td><td valign="top">OTHER_NUMBER<br /></td></tr><tr><td valign="top">Zs<br /></td><td valign="top"><br /></td><td valign="top">SPACE_SEPARATOR<br /></td></tr><tr><td valign="top">Zl<br /></td><td valign="top"><br /></td><td valign="top">LINE_SEPARATOR<br /></td></tr><tr><td valign="top">Zp<br /></td><td valign="top"><br /></td><td valign="top">PARAGRAPH_SEPARATOR<br /></td></tr><tr><td valign="top">Cc<br /></td><td valign="top"><br /></td><td valign="top">CNTRL<br /></td></tr><tr><td valign="top">Cf<br /></td><td valign="top"><br /></td><td valign="top">FORMAT<br /></td></tr><tr><td valign="top">Co<br /></td><td valign="top"><br /></td><td valign="top">PRIVATE_USE<br /></td></tr><tr><td valign="top">Cs<br /></td><td valign="top"><br /></td><td valign="top">SURROGATE<br /></td></tr><tr><td valign="top">Pd<br /></td><td valign="top"><br /></td><td valign="top">DASH_PUNCTUATION<br /></td></tr><tr><td valign="top">Ps<br /></td><td valign="top"><br /></td><td valign="top">START_PUNCTUATION<br /></td></tr><tr><td valign="top">Pe<br /></td><td valign="top"><br /></td><td valign="top">END_PUNCTUATION<br /></td></tr><tr><td valign="top">Pc<br /></td><td valign="top"><br /></td><td valign="top">CONNECTOR_PUNCTUATION<br /></td></tr><tr><td valign="top">Po<br /></td><td valign="top"><br /></td><td valign="top">OTHER_PUNCTUATION<br /></td></tr><tr><td valign="top">Sm<br /></td><td valign="top"><br /></td><td valign="top">MATH_SYMBOL<br /></td></tr><tr><td valign="top">Sc<br /></td><td valign="top"><br /></td><td valign="top">CURRENCY_SYMBOL<br /></td></tr><tr><td valign="top">Sk<br /></td><td valign="top"><br /></td><td valign="top">MODIFIER_SYMBOL<br /></td></tr><tr><td valign="top">So<br /></td><td valign="top"><br /></td><td valign="top">OTHER_SYMBOL<br /></td></tr><tr><td valign="top">L<br /></td><td valign="top"><br /></td><td valign="top">LETTER<br /></td></tr><tr><td valign="top">M<br /></td><td valign="top"><br /></td><td valign="top">MARK<br /></td></tr><tr><td valign="top">N<br /></td><td valign="top"><br /></td><td valign="top">NUMBER<br /></td></tr><tr><td valign="top">Z<br /></td><td valign="top"><br /></td><td valign="top">SEPARATOR<br /></td></tr><tr><td valign="top">C<br /></td><td valign="top"><br /></td><td valign="top">CONTROL<br /></td></tr><tr><td valign="top">P<br /></td><td valign="top"><br /></td><td valign="top">PUNCTUATION<br /></td></tr><tr><td valign="top">S<br /></td><td valign="top"><br /></td><td valign="top">SYMBOL</td></tr><tr><td valign="top">LD<br /></td><td valign="top"><br /></td><td valign="top">LETTER_OR_DIGIT<br /></td></tr><tr><td valign="top">L1<br /></td><td valign="top"><br /></td><td valign="top">Latin-1<br /></td></tr><tr><td valign="top">all<br /></td><td valign="top"><br /></td><td valign="top">ALL<br /></td></tr><tr><td valign="top">ASCII<br /></td><td valign="top"><br /></td><td valign="top">ASCII<br /></td></tr><tr><td valign="top">Alnum<br /></td><td valign="top"><br /></td><td valign="top">字母数字(0-9,a-z,A-Z)<br /></td></tr><tr><td valign="top">Alpha<br /></td><td valign="top"><br /></td><td valign="top">字母(a-z,A-Z)<br /></td></tr><tr><td valign="top">Blank<br /></td><td valign="top"><br /></td><td valign="top">空格和制表符(' '|\t)<br /></td></tr><tr><td valign="top">Cntrl<br /></td><td valign="top"><br /></td><td valign="top">控制字符，不可打印<br /></td></tr><tr><td valign="top">Digit<br /></td><td valign="top"><br /></td><td valign="top">数字(0-9)<br /></td></tr><tr><td valign="top">Graph<br /></td><td valign="top"><br /></td><td valign="top">可打印且可视字母（例如空格' '是可打印的但不是可视字母，而 `a' 两者都是。）<br /></td></tr><tr><td valign="top">Lower<br /></td><td valign="top"><br /></td><td valign="top">小写字母<br /></td></tr><tr><td valign="top">Print<br /></td><td valign="top"><br /></td><td valign="top">可打印字母（非控制字符）<br /></td></tr><tr><td valign="top">Punct<br /></td><td valign="top"><br /></td><td valign="top">标符号（字母、数字、控制、空白符以外的字母），如：!@#$%}{&lt;&gt;,./?[]等等。<br /></td></tr><tr><td valign="top">Space<br /></td><td valign="top"><br /></td><td valign="top">空白符(' ',\t,0x09,0x0A,0x0B,0x0C,0x0D,0x20)<br /></td></tr><tr><td valign="top">Upper<br /></td><td valign="top"><br /></td><td valign="top">大写字母<br /></td></tr><tr><td valign="top">XDigit<br /></td><td valign="top"><br /></td><td valign="top">十六进制数字(0-9，a-f, A-F)<br /></td></tr></tbody></table><br /><hr width="100%" size="2" /><br /><br /><br /><h3><a name="man_subexp"></a>替换表达式</h3><a name="subexp_chars"></a>特殊字符<br /><table cellspacing="2" cellpadding="2" width="100%" border="1"><tbody><tr><td valign="top" width="30%">特殊字符介绍<br /></td><td valign="top">描述<br /></td></tr><tr><td valign="top" width="30%">\n<br /></td><td valign="top">换行<br /></td></tr><tr><td valign="top" width="30%">\b<br /></td><td valign="top">向前删除一个字符。当这个字符位于替换串之首时，将删除匹配串之前的一个字符。若匹配串位于行首，将使匹配串所在行与前一行相合并。<br /></td></tr><tr><td valign="top" width="30%">\d<br /></td><td valign="top">向后删除一个字符。当这个字符位于替换串之末时，将删除匹配串之后的一个字符。若匹配串位于行末，将使匹配串所在行与下一行相合并。<br /></td></tr><tr><td valign="top" width="30%">\e<br /></td><td valign="top">插入一个ESC字符<br /></td></tr><tr><td valign="top">\t<br /></td><td valign="top">插入一个TAB字符<br /></td></tr><tr><td valign="top">\<i><b>n</b></i><br /></td><td valign="top">n代表查找正则表达式中的子表达式（组）。\1代表第一个子表达式，\2代表第二个子表达式，依次类推。\0代表整个匹配到的字符串。<br /></td></tr><tr><td valign="top">\v<br /></td><td valign="top">大写下一个字母<br /></td></tr><tr><td valign="top">\U<br /></td><td valign="top">全部大写以后的字母，直到碰到其它指示符为止。<br /></td></tr><tr><td valign="top">\l<br /></td><td valign="top">小写下一个字母<br /></td></tr><tr><td valign="top">\L<br /></td><td valign="top">全部小写以后的字母，直到碰到其它指示符为止。<br /></td></tr><tr><td valign="top">\E<br /></td><td valign="top">取消所有的字母大小写指示符。<br /></td></tr></tbody></table><br /><br /><a name="subexp_custtbl"></a>自定义替换表<br /><br />在查找／替换中使用自定义替换表 <br />有的时候，上述简单的自定义替换功能是不够的。例如，用户可能希望只把出现在括号内的源串替换为目标串。这种文本处理可以通过在查找/替换中使用自定义替换表来解决。 <br /><br />在查找/替换功能中使用自定义替换表的替换函数是\Tn，其中n是0-9的数字， 注意n为0表示第10张替换表。如果略去n，其效果相当于\T1，即使用第一张替换表。例如要把所有放在方括号中的汉字替换为拼音，可以查找“\[(\E)\]”，替换为“\T{\1}”。即把第一个子表达式的匹配内容按自定义替换表转换。注意，如果\T函数的参数不在替换表的源串中，\T函数的结果与源串相同，即不做任何变换。 <br /><br />有些情况下，用户可能希望只使用替换表的一部分内容。还是以拼音为例，前面给出的替换表中包含了拼音的音调，如果在替换时不希望加上这些音调数字，可以使用“过滤”功能。所谓过滤，其实是用一个正则表达式去分析替换表的目标串，并把其中的某个子表达式取出来。 <br /><br />使用“过滤”时，在“设置自定义替换表”对话框中，点“过滤”按钮，在弹出的对话框中填入一个正则表达式。再以拼音为例，表达式可以写为“(\p{Alpha}+)(\d)”，其中第一对括号中的是不含音调的拼音，第二对括号是音调。在调用\T函数时，JTextPro会在目标串中查找这个正则表达式。但是如何把其中的子表达式取出来呢？\T函数还有一个可选的下标，取第n个子表达式的值就写作\T{...}[n]。所以，把放在方括号中的汉字替换为不带调的拼音，可以查找“\[(\E)\]”，替换为“\T{\1}[1]” <br /><br /><br /><br /><br /><img src ="http://www.blogjava.net/zhugf000/aggbug/23414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-12 09:16 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/12/23414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>减少全局竞争性同步，提高应用的垂直扩展能力</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/12/23411.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Mon, 12 Dec 2005 01:05:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/12/23411.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/23411.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/12/23411.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/23411.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/23411.html</trackback:ping><description><![CDATA[<P>减少全局竞争性同步，提高应用的垂直扩展能力</P>
<P>垂直扩展，简单的说，是当单一系统硬件升级扩展时，如增加CPU，内存，应用程序能够随之线性提高业务处理能力。<BR>多线程是服务端 Java 应用的标准处理方式，其优点不用赘述。本文要讨论的是，如何在设计阶段降低多线程之间的竞争性同步开销。</P>
<P>假设一个Web应用，需要为当前用户维护在线用户信息。此用户信息列表会放在 Application 范围的一个 Map 中，那么我们增加或删除一个在线用户的操作会是这样：。<BR>Map clientMap = ...// from Application Context<BR>synchronized(clientMap){<BR>&nbsp;clientMap.put(clientId,clientObject);<BR>}<BR>这是一个典型的全局同步代码，当并发线程增加时，这部分代码就有可能会存在潜在垂直扩展瓶颈。</P>
<P>最简单解决办法：用 ConcurrentHashMap。<BR>ConcurrentHashMap的多线程下的表现要比HashMap好的多，可以做到随着线程数增长性能基本保持稳定。<BR>参见：<A href="http://www-128.ibm.com/developerworks/cn/java/j-jtp07233/index.html">http://www-128.ibm.com/developerworks/cn/java/j-jtp07233/index.html</A><BR>对 ConcurrentHashMap 的分析，参见：<A href="http://www-128.ibm.com/developerworks/cn/java/j-jtp08223/index.html">http://www-128.ibm.com/developerworks/cn/java/j-jtp08223/index.html</A></P>
<P><BR>在 ConcurrentMap/ConcurrentLinkedQueue 不能帮助我们的情况下，我们需要明确设计以避免全局竞争。<BR>基本原则是：<BR>1 预分配，降低争用出现的频率。<BR>2 降低锁的粒度，将全局竞争变为局部竞争。</P>
<P>预分配策略示例：<BR>对于一在线交易处理系统，需要为每个交易生成交易流水号，假设有多台交易服务器按照集群方式配置，同时提供服务。那么需要在交易服务器之间进行同步，以保证交易流水号的正常增长。<BR>一种处理方式为：在数据库中保存当前交易流水号的最高值，每台机器一次预分配1000流水，内部采用线程同步进行分配，用完再从数据库分配。这里数据库充当了全局存储和全局同步工具，如果每来一条交易，就访问一次数据库，考虑到数据库同步和事务的负担，这里会成为严重的性能瓶颈。</P>
<P>降低锁粒度策略示例：<BR>1 ConcurrentHashMap 本身就是个很好的模范。它采用32颗锁，来代替普通 HashMap 的单颗对象锁。<BR>2 对于数据库中并发大的表，可以考虑将表级锁改为行级锁，提高并发性。<BR><FONT size=1><BR>暂时想不起来示例，有空再补</FONT></P><img src ="http://www.blogjava.net/zhugf000/aggbug/23411.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-12 09:05 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/12/23411.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDK 1.5 对超大字符集的支持</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/09/23108.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Fri, 09 Dec 2005 03:27:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/09/23108.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/23108.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/09/23108.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/23108.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/23108.html</trackback:ping><description><![CDATA[<P><STRONG>JDK 1.5 对超大字符集的支持</STRONG></P>
<P><STRONG>Unicode 与超大字符集</STRONG><BR>国标 GB18030 规定了4字节扩展部分，这部分区域目前在 Unicode 规范中作为CJK Ext B区存在，即常说的中文超大字符集。这部分区域编码为 \U20000 - \U2A6D6。</P>
<P>&nbsp;</P>
<P><STRONG>UTF-16与Java String/Character 对象</STRONG><BR>一个完整的 Unicode 字符叫 代码点/CodePoint，而一个 Java char 叫 代码单元 code unit。<BR>String 对象以UTF-16保存 Unicode 字符，需要用2个字符表示一个 超大字符集的汉字，这这种表示方式称之为 Surrogate，第一个字符叫 Surrogate High，第二个就是 Surrogate Low。</P>
<P>判断一个char是否是 Surrogate 区的字符，用 Character的 isHighSurrogate()/isLowSurrogate()方法。<BR>从两个Surrogate High/Low 字符，返回一个完整的 Unicode CodePoint 用 Character.toCodePoint()/codePointAt()方法。</P>
<P>一个 Code Point ，可能需要一个也可能需要两个char表示，因此不能直接使用 CharSequence.length()方法直接返回一个字符串到底有多少个汉字，而需要用String.codePointCount()/Character.codePointCount()。</P>
<P>要定位字符串中的第N个字符，不能直接将 N 作为偏移量，而需要从字符串头部依次遍历得到，需要用String/Character.offsetByCodePoints() 方法。</P>
<P>从字符串的当前字符，找到上一个字符，也不能直接用offset -- 实现，而需要用 String.codePointBefore()/Character.codePointBefore()，或用 String/Character.offsetByCodePoints()</P>
<P>从当前字符，找下一个字符，不能直接用 offset ++ 实现，需要判断当前 CodePoint 的长度后，再计算得到，或用 String/Character.offsetByCodePoints() 。</P>
<P><BR><STRONG>Swing 对 超大字符集的支持<BR></STRONG>JTextPane增加了对 超大字符集的支持，只要设置字体正确，就可以显示和编辑超大字符集。<BR></P><img src ="http://www.blogjava.net/zhugf000/aggbug/23108.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-09 11:27 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/09/23108.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>业务驱动用例测试</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/08/22993.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Thu, 08 Dec 2005 09:09:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/08/22993.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/22993.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/08/22993.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/22993.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/22993.html</trackback:ping><description><![CDATA[<P><STRONG>业务驱动用例测试</STRONG></P>
<P><BR><STRONG>笨笨所知的测试大致分类</STRONG></P>
<P>单元测试/Unit test<BR>基于代码中类或函数一级的测试</P>
<P>用例测试/Use case test.<BR>基于一个完整业务用例的测试，可以不包括用户业务系统环境的完整操作流程。<BR>如，银行网银系统的转账测试可以认为是一个完整业务用例测试，但是不必要要求测试用例先执行登录过程，再进行转账业务代码的测试。</P>
<P><BR>集成测试/Integration test<BR>由业务人员主导，业务系统作为一个完整黑盒，测试系统功能和性能。</P>
<P>用户接受测试/User Accept test<BR>集成测试通过后，用户基于生产系统剥离的实际数据，再一次对业务系统执行测试；如果集成测试不充分，可以再一次有机会暴露系统的缺陷。</P>
<P>&nbsp;</P>
<P><BR><STRONG>项目实施过程与测试</STRONG></P>
<P>从项目的实施过程来说，单元测试是程序员自测，算在开发阶段，集成测试和用户接受测试所占用时间能够达到项目代码开发阶段的一倍到两倍，大型项目的测试阶段可能还要长。<BR>而用例级测试目前很少作为一个正式的阶段在项目实施过程中存在，或由程序员自行自测，或合并到集成测试过程中。</P>
<P>对于大型业务系统，集成测试和用户测试所花费的主要工作量如下，可能不全。<BR>1 数据准备，测试人员调配准备。<BR>2 测试过程中，测试人员要找到哪些测试数据还能用，再手工操作系统界面，执行测试过程。对于大型业务系统来说，可用测试数据是随着测试进展不断变化的，很有可能某个用户数据刚刚状态正常，现在就欠费了。要想找到合适的数据来测试系统，这是个费劲且混乱的过程。<BR>3 集成回归测试，业务系统如果有升级或改动，需要将所有交易重新测试一遍，以防止变更给原有代码引入缺陷。</P>
<P><BR><STRONG>用例测试<BR></STRONG>用例测试关注业务。<BR><IMG height=398 alt=usecase_test.gif src="http://www.blogjava.net/images/blogjava_net/zhugf000/usecase_test.gif" width=686 border=0><BR>用例测试集中在业务服务这一层，业务服务直接对应了业务用例。<BR>用例测试注重业务服务运行环境的模拟和重现，从而支持业务服务层的自动测试。</P>
<P><BR>用例测试的价值<BR>1 减少集成测试的时间和成本，降低集成测试发现缺陷数，从而降低项目总缺陷修复代价。<BR>&nbsp;用例测试缺陷修复代价远低于集成测试的缺陷修复代价；用例测试发现大部分缺陷后，集成测试就相对轻松了。<BR>2 可回归的用例测试支持快速代码重构。<BR>3 ...</P>
<P><BR><STRONG>单元测试无法覆盖用例测试<BR></STRONG>业务代码运行需要底层资源如数据库或其它业务系统配合，单元测试工具缺乏提供业务服务运行所需环境的模拟，从Junit系列单元测试工具来说，它还是主要从技术角度考虑，从业务角度的考虑如：<BR>底层资源（数据库，JMS）模拟<BR>依赖服务模拟<BR>服务访问模拟<BR>自动检测、重放和比对服务运行时的输入输出参数、资源、依赖服务。<BR>服务接口变动波及分析</P>
<P><BR><STRONG>代码重构的成本<BR></STRONG>代码重构需要付出代价。集成测试费时费力，但用户不可能因为程序员说“我保证代码重构不会改变系统功能”，就不对变动后代码进行测试。<BR>用例回归测试支持可以以较小代价支持代码重构，因为它可在业务服务级自动对功能进行验证，集成测试工作能够相应的减少。<BR></P><img src ="http://www.blogjava.net/zhugf000/aggbug/22993.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-08 17:09 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/08/22993.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 多线程或内存泄漏缺陷排查的一些经验</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/07/22890.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Wed, 07 Dec 2005 09:07:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/07/22890.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/22890.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/07/22890.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/22890.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/22890.html</trackback:ping><description><![CDATA[<P><STRONG>Java 多线程或内存泄漏缺陷排查的一些经验</STRONG></P>
<P><BR><STRONG>JVM Thread DUMP 基本功</STRONG><BR>Windows 下用Ctrl-Break,Unix 下用 kill -3 &lt;pid&gt; 的命令让JVM输出 thread dump。<BR>每隔几秒 thread dump 一次，多做几次，分析比较。</P>
<P><STRONG>Thread Dump分析的一些经验<BR></STRONG>1 找出这几次Thread dump 文件中，有哪些 Java Thread 处于长时间等待状态，很有可能就是问题之所在。<BR>2 如果Java 线程等在某些不可能出错的地方，如 java.lang.XXX/java.util.XXX对象的某个方法，则很有可能是因为出现了 OutOfMemoryError 异常，原因不外乎是JVM 堆内存过小或出现内存泄漏。<BR>3 对于死锁，最直接的表现就是至少两个线程长时间等待相互持有的对象（每个线程所持有的对象和它当前等待的对象都可以从 dump 中看到）。<BR>4 对于死循环，要辅助CPU占用率确定；如果发现CPU至少一颗使用率为100%，并且有线程长时间位于用户代码处，则很有可能是死循环引起。</P>
<P><BR><STRONG>多线程缺陷排查<BR></STRONG>对于Java死锁问题很少出现，多线程访问变量时冲突很常见。<BR>一般出在多线程共享同一对象实例如全局Map，Servlet,Interceptor，或如多线程同时访问某个静态方法，而此静态方法不巧又访问另一个静态变量。<BR>这类问题自测发现不了，在并发压力测试时才能发现。如果代码的入口检查做得好，多半会抛出一些莫名其妙的异常；要不然就会出现正常运行但数据库记录不对的情况。<BR>对这种问题，并无多好的办法解决，主要还是靠看异常堆栈和静态代码分析来解决。<BR><BR><BR><STRONG>内存泄漏排查</STRONG><BR>一般用商用辅助工具排查，但有可能出现在JVM heap dump 模式下，运行极度缓慢的情况。<BR>笨笨曾经用过一个非常简单的工具，效果不错，它可以做到在不影响jvm 执行速度的情况下，做heap dump，然后对dump出的文件进行排序，检查即可。</P>
<P>heapprofile(<A href="http://www.virtualmachine.de/">http://www.virtualmachine.de/</A>)</P>
<P>&nbsp;</P><img src ="http://www.blogjava.net/zhugf000/aggbug/22890.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-07 17:07 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/07/22890.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>With or Without EJB?</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/07/22878.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Wed, 07 Dec 2005 07:54:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/07/22878.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/22878.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/07/22878.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/22878.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/22878.html</trackback:ping><description><![CDATA[<P><STRONG>With&nbsp;or Without EJB?</STRONG></P>
<P><BR><STRONG>EJB 运行时所享受的 J2EE 基础服务</STRONG></P>
<P>1 参与AppServer 提供分布式事务管理(JTA,JTS)。<BR>2 AppServer 提供高性能通讯框架(基于RMI 或 IIOP实现)和大并发处理。<BR>&nbsp;1) AppServer 如 WebLogic/WebSphere 替换了 Sun 标准 RMI 实现（基于著名的多线程阻塞IO），国内的 Apusic 4 则基于纯 NIO 的 IIOP通讯协议实现EJB 远程通讯。 <BR>&nbsp;2) AppServer 提供 EJB 实例池、请求队列、执行线程池等等服务。</P>
<P>3 AppServer 提供透明 EJB 集群管理（负载均衡、故障恢复），保证应用的处理能力能够水平扩展。<BR>4 J2EE 安全体系<BR>5 AppServer 特有的附加增值服务<BR>&nbsp;1) 如 WebLogic WTC EJB，可实现从TUXEDO Service(C语言) 高性能访问 EJB。</P>
<P>&nbsp;</P>
<P><BR><STRONG>大型项目所关注的重点</STRONG></P>
<P>对于大型项目如全国集中这一级别而言，它所关注的重点风险反而是系统的性能、吞吐量、稳定性、高可用性这样的一些基本属性，这里并非说具体的业务功能就不重要；而是与上述的基本属性相比，业务功能可以说是相对的不重要。<BR>基本属性如果有某一项没有达到，直接后果就是项目失败，或者运行时存在高风险。<BR>业务功能则主要是堆时间、堆人、堆代码、堆测试人员的问题，如果实在来不及了，那就放到第二期去做好了，不影响主旋律么。</P>
<P>对于大型项目而言，采用新技术的关注点主要是：<BR>1 能否满足基本质量属性，无重大运行时风险。<BR>比如说，数据访问层，从性能和稳定性角度而言，还算直接采用 JDBC 编码合适，最多采用SQL映射型JDO。对于带缓冲的JDO实现则不宜采用，会带来水平扩展和稳定性风险。</P>
<P>2 项目组相关人员是否有此技术的经验，最好不要付出学习成本，避免因不熟悉所带来的风险。</P>
<P>&nbsp;</P>
<P><BR><STRONG>EJB 和 IoC 框架如 Spring 的定位比较</STRONG></P>
<P>Spring IoC/Context/AOP 可以认为是一个代码组织(Assembler)框架，关注代码如何组织和去耦。</P>
<P>EJB 则是运行结构，关注我们的应用如何运行，如何做集群，系统计算资源如何分配等等。<BR>EJB 3 的改进主要还是从代码组织角度做出的，对于 EJB 运行时架构并没有多少变化（如果说错了，还请指正）；BEA 还有过将 EJB 3的代码翻译为 EJB 2.1 运行时架构的考虑（参见 BEA 的关于 EJB 3 的一篇文章<A href="http://www.javaworld.com/javaworld/jw-08-2004/jw-0809-ejb_p.html">http://www.javaworld.com/javaworld/jw-08-2004/jw-0809-ejb_p.html</A>）。<BR><BR>从上述角度来看，EJB 和 Spring 是从不同的角度看待应用，我们完全可以做到用 Spring 组织代码实现EJB。</P>
<P><BR><STRONG>With or Without EJB?</STRONG><BR>从上述讨论可以看出，用Spring还是用EJB并不是个问题，最终还是看用户的实际需求而定。小Web项目多半不关注性能、并发、集群等等属性，出于开发过程简单和学习成本的考虑，完全可以不用EJB；而大型项目可能还是得用EJB。<BR></P><img src ="http://www.blogjava.net/zhugf000/aggbug/22878.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-07 15:54 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/07/22878.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于Java的高性能TP Monitor的设想</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/06/22747.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Tue, 06 Dec 2005 09:49:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/06/22747.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/22747.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/06/22747.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/22747.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/22747.html</trackback:ping><description><![CDATA[目前的高性能TP Monitor如 TUXEDO CICS全部是基于 C/多进程开发而成<BR><BR>国内市场被BEA/IBM高度垄断，可能也就&nbsp;东方通TongEASY的能虎口夺食。<BR><BR>从TP Monitor的在金融业的应用经验来看，TP Monitor主要作用是：<BR>1 提供一个高性能、高稳定的通讯框架：（如银行总分互联、应用之间互联）<BR>2 支持大并发的交易处理平台（在线交易实时处理，但一般不作为事务管理器，因为全局事务代价过高，主要用数据库自身事务机制）。<BR>3&nbsp;支持软件负载均衡，支持水平扩展（如：TUXEDO MP）。<BR><BR>开源App Server如Jboss/Jonas 全部采用纯Java实现，性能是个问题，跟TUXEDO/CICS相比。<BR><BR>假设我们要自行实现一个可用的TP Monitor，必须要解决上述几点。<BR><BR><BR>从Java的性能来看，它的内部代码执行效率不低，主要弱在：<BR>1 socket通讯效率低<BR>2 ipc机制不支持<BR>3 数据库访问效率低（实际的交易实现效率低，不管用EJB还是POJO）<BR><BR>目前有考虑<BR>1 高性能的通讯框架，必须采用C代码实现。Java做不到Zero Copy，并且JNI在Java和本地C代码之间复制内存代价也很高。<BR>2 大并发的处理平台，这个是Java的优势所在，Java对于同步、并发的实现，写起来简单<BR>3 IPC支持（SystemV消息队列、共享内存、信号灯），标准 Java 库缺乏，但是可以通过JNI实现，实现策略可以参考SWT的实现策略。<BR>4 用户SERVICE实现（数据库访问），采用C实现，充分利用高效的数据库本地接口。<BR><img src ="http://www.blogjava.net/zhugf000/aggbug/22747.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-06 17:49 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/06/22747.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不间断运行工作系统元数据更新策略</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/02/22260.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Fri, 02 Dec 2005 08:40:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/02/22260.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/22260.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/02/22260.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/22260.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/22260.html</trackback:ping><description><![CDATA[<P><STRONG>关键在于元数据更新的事务性</STRONG><BR><BR>一般做法如下：<BR><IMG height=469 alt=meta_refresh.gif src="http://www.blogjava.net/images/blogjava_net/zhugf000/meta_refresh/meta_refresh.gif" width=922 border=0><BR><BR><STRONG>主动检查</STRONG>：每个进程内，有一个定时检查模块，定时检查数据库中元数据表的最后更新时间戳，发现需要重新加载的元数据。<BR><STRONG>被动通知</STRONG>：每个进程内，有一个等待更新消息通知的消息驱动Bean模块，接受元数据管理机发出的元数据更新JMS消息/MQ消息，更新指定元数据。<BR><BR><STRONG>元数据更新的事务性</STRONG>：为保证业务处理模块不受元数据更新过程的影响；在程序设计上，采用双内存切换机制。即内存中，同时有两块内存用于存放元数据。任一时刻，元数据全局变量指向其中一块，为当前工作元数据内存块；元数据检查更新模块，则使用另一块内存，在元数据加载、校验过程结束后，再切换元数据全局变量指向新的元数据内存块；切换元数据全局变量的过程自身受共享锁保护。从而保证业务处理模块的处理过程不受后台元数据切换的影响，并且业务处理模块所访问的元数据始终是可用的，不会出现业务处理过程中，元数据变化的情况。</P>
<P>对于分布式应用，有可能需要自行编写元数据更新的分布式事务管理器，自行实现元数据更新的两阶段提交过程。如果想偷懒，也可以考虑用JCA自行实现Resource Manager，借用应用服务器的Transaction Manager。<BR><BR></P><img src ="http://www.blogjava.net/zhugf000/aggbug/22260.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-02 16:40 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/02/22260.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 与 C 性能比较的一些经验数据</title><link>http://www.blogjava.net/zhugf000/archive/2005/12/02/22257.html</link><dc:creator>笨笨</dc:creator><author>笨笨</author><pubDate>Fri, 02 Dec 2005 08:17:00 GMT</pubDate><guid>http://www.blogjava.net/zhugf000/archive/2005/12/02/22257.html</guid><wfw:comment>http://www.blogjava.net/zhugf000/comments/22257.html</wfw:comment><comments>http://www.blogjava.net/zhugf000/archive/2005/12/02/22257.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.blogjava.net/zhugf000/comments/commentRss/22257.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhugf000/services/trackbacks/22257.html</trackback:ping><description><![CDATA[<P>Java 与 C 性能比较的一些经验数据<BR><BR>太细的数据也拿不到，必须要针对具体平台和JVM</P>
<P><STRONG>基本代码执行</STRONG><BR>Java与C在 1:3-1:5左右，在Intel平台上用JDK1.4测得。<BR>JNI不快，一次基本JNI调用差不多等于一次Java方法调用（未考虑大数据量传输）</P>
<P><STRONG>数据库访问</STRONG><BR>JDBC与数据库本地接口差距较大，差不多在1到2个数量级左右，或更多。可以认为在1:10 - 1:50之间</P>
<P><STRONG>socket网络传输</STRONG><BR>Java要分普通多线程和NIO方式<BR>多线程方式，并发受限，一般不会超过150-200个并发，再多性能不会增加。这种方式下，网络传输性能与C差距可以认为在1个数量级左右，即1:10-1:30。<BR>NIO方式，并发不错，能够支持到几千个并发，性能差距小些，可以做到在1:3 -- 1:5 左右。<BR>C 通过select/poll/epoll技术，并发10000没有多少问题，并且通过Zero-Copy技术，可以避开Java 所无法避免缓冲区复制(Java-&gt;C缓冲区复制)的问题。</P>
<P>总的来看，Java与C在普通多层Web应用方面，差距可以认为在1个数量级左右，关键应用如TP Monitor目前还无法使用Java。<BR></P><img src ="http://www.blogjava.net/zhugf000/aggbug/22257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhugf000/" target="_blank">笨笨</a> 2005-12-02 16:17 <a href="http://www.blogjava.net/zhugf000/archive/2005/12/02/22257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>