﻿<?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-&lt;font size=4&gt;天快黑了的日志&lt;/font&gt;</title><link>http://www.blogjava.net/zhvfeng/</link><description>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;分享知识、分享快乐&lt;/i&gt;</description><language>zh-cn</language><lastBuildDate>Sat, 16 May 2026 17:17:14 GMT</lastBuildDate><pubDate>Sat, 16 May 2026 17:17:14 GMT</pubDate><ttl>60</ttl><item><title>谁能解决多个MDB读取JBoss Topic上的BytesMessage出现的奇怪问题</title><link>http://www.blogjava.net/zhvfeng/archive/2010/08/24/329795.html</link><dc:creator>天快黑了</dc:creator><author>天快黑了</author><pubDate>Tue, 24 Aug 2010 07:54:00 GMT</pubDate><guid>http://www.blogjava.net/zhvfeng/archive/2010/08/24/329795.html</guid><wfw:comment>http://www.blogjava.net/zhvfeng/comments/329795.html</wfw:comment><comments>http://www.blogjava.net/zhvfeng/archive/2010/08/24/329795.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhvfeng/comments/commentRss/329795.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhvfeng/services/trackbacks/329795.html</trackback:ping><description><![CDATA[2个不同的MDB监听JBoss 4.2.3 上的同一个Topic (集成JBoss Messaging 1.4.2 SP1)，Topic上的消息是BytesMessage。发一个消息到Topic上，2个MDB都会收到这个消息。<br />
<br />
但奇怪的是只有一个MDB能正常读取BytesMesage，另一个MDB读取BytesMessage.<font style="background-color: #c0c0c0">readBytes</font>()始终返回-1<br />
<br />
同样的测试程序，在WebLogic上就正常。<br />
<br />
JBoss怎么会发送同一个BytesMessage对象到所有的subscriber？有人解决过同样的问题吗？ <br />
<br />
<br />
google了很长时间，也尝试了很多方法，似乎没什么好的办法。一种方法是避免使用BytesMessage, 还有一种方法就是使用反射，直接复制JBoss的BytesMessage实现。<br />
<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><img id="Codehighlighter1_35_358_Open_Image" onclick="this.style.display='none'; Codehighlighter1_35_358_Open_Text.style.display='none'; Codehighlighter1_35_358_Closed_Image.style.display='inline'; Codehighlighter1_35_358_Closed_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif"  alt="" /><img style="display: none" id="Codehighlighter1_35_358_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_35_358_Closed_Text.style.display='none'; Codehighlighter1_35_358_Open_Image.style.display='inline'; Codehighlighter1_35_358_Open_Text.style.display='inline';" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif"  alt="" /><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;onMessage(Message&nbsp;msg)&nbsp;</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_35_358_Closed_Text"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_35_358_Open_Text"><span style="color: #000000">{<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" /><br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;BytesMessageProxy&nbsp;msgProxy&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(BytesMessageProxy)msg;<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&nbsp;clazz&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;MessageProxy.</span><span style="color: #0000ff">class</span><span style="color: #000000">;<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Field&nbsp;field&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;clazz.getDeclaredField(</span><span style="color: #000000">"</span><span style="color: #000000">message</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;field.setAccessible(</span><span style="color: #0000ff">true</span><span style="color: #000000">);<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JBossMessage&nbsp;rawMsg&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(JBossMessage)field.get(msgProxy);<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BytesMessage&nbsp;newMsg&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(BytesMessage)rawMsg.doCopy();<br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" /><br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;read&nbsp;data&nbsp;from&nbsp;newMsg</span><span style="color: #008000"><br />
<img align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif"  alt="" /></span><span style="color: #000000">}</span></span></div>
<img src ="http://www.blogjava.net/zhvfeng/aggbug/329795.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhvfeng/" target="_blank">天快黑了</a> 2010-08-24 15:54 <a href="http://www.blogjava.net/zhvfeng/archive/2010/08/24/329795.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java虚拟机探险之Class Loader</title><link>http://www.blogjava.net/zhvfeng/archive/2010/08/17/329078.html</link><dc:creator>天快黑了</dc:creator><author>天快黑了</author><pubDate>Tue, 17 Aug 2010 02:47:00 GMT</pubDate><guid>http://www.blogjava.net/zhvfeng/archive/2010/08/17/329078.html</guid><wfw:comment>http://www.blogjava.net/zhvfeng/comments/329078.html</wfw:comment><comments>http://www.blogjava.net/zhvfeng/archive/2010/08/17/329078.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhvfeng/comments/commentRss/329078.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhvfeng/services/trackbacks/329078.html</trackback:ping><description><![CDATA[&nbsp;
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">众所周知，所有的</span><span style="font-size: 12pt">Java class</span><span style="font-family: 宋体; font-size: 12pt">文件都是由</span><span style="font-size: 12pt">JVM</span><span style="font-family: 宋体; font-size: 12pt">（虚拟机）加载并执行的。</span><span style="font-family: 宋体; font-size: 12pt">深入理解</span><span style="font-size: 12pt">JVM</span><span style="font-family: 宋体; font-size: 12pt">对于我们提高</span><span style="font-size: 12pt">Java</span><span style="font-family: 宋体; font-size: 12pt">技术和解决</span><span style="font-size: 12pt">Java</span><span style="font-family: 宋体; font-size: 12pt">问题都有非常大的帮助。</span></p>
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-size: 12pt">JVM</span><span style="font-family: 宋体; font-size: 12pt">内部主要包括内存管理和</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">（类加载器）两个部分。熟悉了内存管理，我们就会清楚程序在内存中是怎么分配和执行的，就能解决所有和对象相关的问题（比如</span><span style="font-size: 12pt">Memory Leak</span><span style="font-family: 宋体; font-size: 12pt">）。理解了</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">，就能解决所有类找不到（比如遇到</span><span style="font-size: 12pt">NoClassDefFoundError</span><span style="font-family: 宋体; font-size: 12pt">或</span><span style="font-size: 12pt">ClassNotFoundException</span><span style="font-family: 宋体; font-size: 12pt">）或配置文件找不到问题。</span></p>
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">这次我们只讨论</span><span style="font-size: 12pt">JVM</span><span style="font-family: 宋体; font-size: 12pt">的</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">，下次再讨论</span><span style="font-size: 12pt">JVM</span><span style="font-family: 宋体; font-size: 12pt">的内存管理。</span></p>
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">的主要作用就是负责查找类并将其加载到内存中。有趣的是，</span><span style="font-size: 12pt">Java</span><span style="font-family: 宋体; font-size: 12pt">中的</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">也是由</span><span style="font-size: 12pt">Java</span><span style="font-family: 宋体; font-size: 12pt">所写，就和普通的</span><span style="font-size: 12pt">class</span><span style="font-family: 宋体; font-size: 12pt">一样。这就产生了一个是鸡生蛋还是蛋生鸡的问题，到底第一个</span><span style="font-size: 12pt">class</span><span style="font-family: 宋体; font-size: 12pt">由谁来加载呢？我们稍后会来讨论这个问题。</span></p>
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">先来看一下</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">所具有的特点。</span></p>
<p style="text-align: left; text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt" class="MsoNormal" align="left"><span style="font-size: 12pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">继承关系</span></p>
<p style="text-align: left; margin-left: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">虽然</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">也是一个</span><span style="font-size: 12pt">Java class</span><span style="font-family: 宋体; font-size: 12pt">，但这里的继承不是指定义</span><span style="font-size: 12pt">class</span><span style="font-family: 宋体; font-size: 12pt">时使用的</span><span style="font-size: 12pt">extends</span><span style="font-family: 宋体; font-size: 12pt">关键字来实现的继承，而是指由属性来维持的继承关系。即通过</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">的构造方法或其它方法显式的设置一个父</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">。</span></p>
<p style="text-align: left; text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt" class="MsoNormal" align="left"><span style="font-size: 12pt">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">代理关系</span></p>
<p style="text-align: left; margin-left: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">每一个</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">在接到请求去加载一个类之前（默认，访问一个类的时候，就会由加载当前类的</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">去加载被访问的类），它会首先请求它的父</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">来尝试加载，依次往上，如果父</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">加载成功，则直接返回，子</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">不再查找。</span></p>
<p style="text-align: left; margin-left: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">否则依次往下查找并加载。如果直到被请求的</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">也没有找到要加载的类，则会出现</span><span style="font-size: 12pt">NoClassDefFoundError</span><span style="font-family: 宋体; font-size: 12pt">或</span><span style="font-size: 12pt">ClassNotFoundException</span></p>
<p style="text-align: left; margin-left: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">当然如果被请求的类已经加载到了内存中，就不会触发这个查找过程了，而是直接返回已经加载的类。</span></p>
<p style="text-align: left; text-indent: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">我们来看一个例子，假设有图</span><span style="font-size: 12pt">1</span><span style="font-family: 宋体; font-size: 12pt">中的</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">层次：</span></p>
<p style="text-align: left; text-indent: 21pt" class="MsoNormal" align="left"><span style="font-size: 12pt"></p>
</span>
<p style="text-align: left; margin-left: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt"><img style="width: 508px; height: 324px" border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/zhvfeng/1.png" width="508" height="324" /><br />
如果我们请求</span><span style="font-size: 12pt">Class Loader E</span><span style="font-family: 宋体; font-size: 12pt">去加载</span><span style="font-size: 12pt">Test.class</span><span style="font-family: 宋体; font-size: 12pt">，首先它会请求父</span><span style="font-size: 12pt">Class Loader D</span><span style="font-family: 宋体; font-size: 12pt">去尝试加载。同样</span><span style="font-size: 12pt">Class Loader D</span><span style="font-family: 宋体; font-size: 12pt">会先请求它的父</span><span style="font-size: 12pt">Class Loader C</span><span style="font-family: 宋体; font-size: 12pt">去尝试加载</span><span style="font-size: 12pt">Test.class</span><span style="font-family: 宋体; font-size: 12pt">。当然这里</span><span style="font-size: 12pt">Class Loader C</span><span style="font-family: 宋体; font-size: 12pt">找不到</span><span style="font-size: 12pt">Test.class</span><span style="font-family: 宋体; font-size: 12pt">，于是转回由</span><span style="font-size: 12pt">Class Loader D</span><span style="font-family: 宋体; font-size: 12pt">去加载。最终</span><span style="font-size: 12pt">Class Loader D</span><span style="font-family: 宋体; font-size: 12pt">成功找到了</span><span style="font-size: 12pt">D:"Test.class</span><span style="font-family: 宋体; font-size: 12pt">，并将其加载到内存中。</span></p>
<p style="text-align: left; margin-left: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">同样，如果我们请求</span><span style="font-size: 12pt">Class Loader F</span><span style="font-family: 宋体; font-size: 12pt">去加载</span><span style="font-size: 12pt">Test3.class</span><span style="font-family: 宋体; font-size: 12pt">。</span><span style="font-size: 12pt">Class Loader C</span><span style="font-family: 宋体; font-size: 12pt">和</span><span style="font-size: 12pt">Class Loader D</span><span style="font-family: 宋体; font-size: 12pt">在各自的搜索范围内都找不到</span><span style="font-size: 12pt">Test3.class</span><span style="font-family: 宋体; font-size: 12pt">。最终会由</span><span style="font-size: 12pt">Class Loader F</span><span style="font-family: 宋体; font-size: 12pt">自己加载</span><span style="font-size: 12pt">F:"Test3.class</span><span style="font-family: 宋体; font-size: 12pt">到内存中。</span></p>
<p style="text-align: left; margin-left: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">如果我们请求</span><span style="font-size: 12pt">Class Loader D</span><span style="font-family: 宋体; font-size: 12pt">去加载</span><span style="font-size: 12pt">Test3.class</span><span style="font-family: 宋体; font-size: 12pt">，最终就会出现</span><span style="font-size: 12pt">NoClassDefFoundError</span><span style="font-family: 宋体; font-size: 12pt">或</span><span style="font-size: 12pt">ClassNotFoundException</span></p>
<p style="text-align: left; text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt" class="MsoNormal" align="left"><span style="font-size: 12pt">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">同一继承链可见性</span></p>
<p style="text-align: left; margin-left: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">在同一个</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">对象的继承链中，下面被加载的类可以访问上面被加载的类，反之则不可以。</span></p>
<p style="text-align: left; text-indent: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">同样以图</span><span style="font-size: 12pt">1</span><span style="font-family: 宋体; font-size: 12pt">为例，</span><span style="font-size: 12pt">Test4.class</span><span style="font-family: 宋体; font-size: 12pt">可以访问到</span><span style="font-size: 12pt">D:"Test.class</span><span style="font-family: 宋体; font-size: 12pt">和</span><span style="font-size: 12pt">C:"Test2.class</span></p>
<p style="text-align: left; margin-left: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">而如果</span><span style="font-size: 12pt">D:"Test.class</span><span style="font-family: 宋体; font-size: 12pt">或</span><span style="font-size: 12pt">C:"Test2.class</span><span style="font-family: 宋体; font-size: 12pt">尝试访问</span><span style="font-size: 12pt">Test4.class</span><span style="font-family: 宋体; font-size: 12pt">，就会出现</span><span style="font-size: 12pt">NoClassDefFoundError</span><span style="font-family: 宋体; font-size: 12pt">或</span><span style="font-size: 12pt">ClassNotFoundException</span></p>
<p style="text-align: left; text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt" class="MsoNormal" align="left"><span style="font-size: 12pt">4.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">多个继承链不可见性</span></p>
<p style="text-align: left; text-indent: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">多个继承链之间彼此看不到对方，不能相互访问。</span></p>
<p style="text-align: left; margin-left: 21pt" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">还以图</span><span style="font-size: 12pt">1</span><span style="font-family: 宋体; font-size: 12pt">为例，如果</span><span style="font-size: 12pt">Test4.class</span><span style="font-family: 宋体; font-size: 12pt">访问</span><span style="font-size: 12pt">Test3.class</span><span style="font-family: 宋体; font-size: 12pt">，或反过来</span><span style="font-size: 12pt">Test3.class</span><span style="font-family: 宋体; font-size: 12pt">访问</span><span style="font-size: 12pt">Test4.class</span><span style="font-family: 宋体; font-size: 12pt">，都会引起</span><span style="font-size: 12pt">NoClassDefFoundError</span><span style="font-family: 宋体; font-size: 12pt">或</span><span style="font-size: 12pt">ClassNotFoundException</span></p>
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">理解了</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">所具有的特点，我们来看看</span><span style="font-size: 12pt">JDK</span><span style="font-family: 宋体; font-size: 12pt">中都预置了哪些</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">。也是</span><span style="font-size: 12pt">JVM</span><span style="font-family: 宋体; font-size: 12pt">启动时默认创建的</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">。如图</span><span style="font-size: 12pt">2<br />
<img style="width: 502px; height: 266px" border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/zhvfeng/2.png" width="502" height="266" /></span></p>
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt"><br />
通过图</span><span style="font-size: 12pt">2</span><span style="font-family: 宋体; font-size: 12pt">，我们可以看到</span><span style="font-size: 12pt">Bootstrap Class Loader</span><span style="font-family: 宋体; font-size: 12pt">是</span><span style="font-size: 12pt">JVM</span><span style="font-family: 宋体; font-size: 12pt">中的祖先</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">。它是</span><span style="font-size: 12pt">JDK</span><span style="font-family: 宋体; font-size: 12pt">中唯一一个由</span><span style="font-size: 12pt">C++</span><span style="font-family: 宋体; font-size: 12pt">所写的</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">，它负责加载</span><span style="font-size: 12pt">JDK</span><span style="font-family: 宋体; font-size: 12pt">的核心类库</span><span style="font-size: 12pt">(rt.jar)</span><span style="font-family: 宋体; font-size: 12pt">以及另外两个由</span><span style="font-size: 12pt">Java</span><span style="font-family: 宋体; font-size: 12pt">所写的</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">（</span><span style="font-size: 12pt">Ext Class Loader</span><span style="font-family: 宋体; font-size: 12pt">和</span><span style="font-size: 12pt">App Class Loader</span><span style="font-family: 宋体; font-size: 12pt">）。之后就功成身退，转由</span><span style="font-size: 12pt">Ext Class Loader</span><span style="font-family: 宋体; font-size: 12pt">和</span><span style="font-size: 12pt">App Class Loader</span><span style="font-family: 宋体; font-size: 12pt">加载所有应用中用到的类。</span></p>
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">一般我们的应用都是通过设置</span><span style="font-size: 12pt">CLASSPATH</span><span style="font-family: 宋体; font-size: 12pt">，最终由</span><span style="font-size: 12pt">App Class Loader</span><span style="font-family: 宋体; font-size: 12pt">来加载。根据</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">的继承关系，我们应用中的类可以访问</span><span style="font-size: 12pt">JDK</span><span style="font-family: 宋体; font-size: 12pt">的核心类库。反之则会出错。</span></p>
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">我们再来看看</span><span style="font-size: 12pt">WebLogic</span><span style="font-family: 宋体; font-size: 12pt">中</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">的层次关系（如图</span><span style="font-size: 12pt">4</span><span style="font-family: 宋体; font-size: 12pt">）。如果需要，大家可以参考一下</span><span style="font-size: 12pt">WebLogic</span><span style="font-family: 宋体; font-size: 12pt">中</span><span style="font-size: 12pt">WAR</span><span style="font-family: 宋体; font-size: 12pt">和</span><span style="font-size: 12pt">EAR</span><span style="font-family: 宋体; font-size: 12pt">的文件结构（如图</span><span style="font-size: 12pt">3</span><span style="font-family: 宋体; font-size: 12pt">）</span></p>
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-size: 12pt"><img style="width: 496px; height: 254px" border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/zhvfeng/3.png" width="496" height="254" /><br />
<br />
<img style="width: 448px; height: 327px" border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/zhvfeng/4.png" width="448" height="327" /><br />
WLS</span><span style="font-family: 宋体; font-size: 12pt">中自定义了很多新的</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">，当然他们的祖先</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">都是</span><span style="font-size: 12pt">JDK</span><span style="font-family: 宋体; font-size: 12pt">中的</span><span style="font-size: 12pt">App (or System) Class Loader</span><span style="font-family: 宋体; font-size: 12pt">。我们来看一下每个</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">的职责。</span></p>
<p style="text-align: left; text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt" class="MsoNormal" align="left"><span style="font-size: 12pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt">JDK App (or System) Class Loader</span></p>
<p style="text-align: left; text-indent: -77.3pt; margin-left: 99pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">负责加载</span><span style="font-size: 12pt">WLS</span><span style="font-family: 宋体; font-size: 12pt">启动脚本中</span><span style="font-size: 12pt">CLASSPATH</span><span style="font-family: 宋体; font-size: 12pt">中设置的类</span></p>
<p style="text-align: left; text-indent: -77.3pt; margin-left: 99pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">所有的类都会最先由它尝试加载</span></p>
<p style="text-align: left; text-indent: -21.7pt; margin-left: 43.4pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">因为</span><span style="font-size: 12pt">CLASSPATH</span><span style="font-family: 宋体; font-size: 12pt">的值在运行期不允许修改，所以由该</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">加载的类在运行期不能被动态卸载（替换）</span></p>
<p style="text-align: left; text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt" class="MsoNormal" align="left"><span style="font-size: 12pt">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt">EJB Class Loader (1)</span></p>
<p style="text-align: left; text-indent: -23.3pt; margin-left: 45pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">负责加载单独的</span><span style="font-size: 12pt">EJB jar</span><span style="font-family: 宋体; font-size: 12pt">里的类。</span></p>
<p style="text-align: left; text-indent: -23.3pt; margin-left: 45pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">不同的</span><span style="font-size: 12pt">EJB jar</span><span style="font-family: 宋体; font-size: 12pt">文件会被不同实例的</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">加载，因此</span><span style="font-size: 12pt">EJB jar</span><span style="font-family: 宋体; font-size: 12pt">彼此之间互相看不到对方</span></p>
<p style="text-align: left; text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt" class="MsoNormal" align="left"><span style="font-size: 12pt">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt">WAR Class Loader (1)</span></p>
<p style="text-align: left; text-indent: -23.3pt; margin-left: 45pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">负责加载单独的</span><span style="font-size: 12pt">WAR</span><span style="font-family: 宋体; font-size: 12pt">里的类</span></p>
<p style="text-align: left; text-indent: -23.3pt; margin-left: 45pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">不同的</span><span style="font-size: 12pt">WAR</span><span style="font-family: 宋体; font-size: 12pt">文件会被不同实例的</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">加载，因此</span><span style="font-size: 12pt">WAR</span><span style="font-family: 宋体; font-size: 12pt">彼此之间互相看不到对方</span></p>
<p style="text-align: left; text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt" class="MsoNormal" align="left"><span style="font-size: 12pt">4.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt">EAR Class Loader</span></p>
<p style="text-align: left; text-indent: -23.3pt; margin-left: 45pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">负责加载</span><span style="font-size: 12pt">EAR</span><span style="font-family: 宋体; font-size: 12pt">里面的</span><span style="font-size: 12pt">APP-INF</span><span style="font-family: 宋体; font-size: 12pt">下的类</span></p>
<p style="text-align: left; text-indent: -23.3pt; margin-left: 45pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">不同的</span><span style="font-size: 12pt">EAR</span><span style="font-family: 宋体; font-size: 12pt">文件会被不同实例的</span><span style="font-size: 12pt">EAR Class Loader</span><span style="font-family: 宋体; font-size: 12pt">加载，因此</span><span style="font-size: 12pt">EAR</span><span style="font-family: 宋体; font-size: 12pt">彼此之间互相看不到对方</span></p>
<p style="text-align: left; text-indent: -23.3pt; margin-left: 45pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">它下面有一个</span><span style="font-size: 12pt">EJB Class Loader (2) </span><span style="font-family: 宋体; font-size: 12pt">实例</span><span style="font-size: 12pt">,</span><span style="font-family: 宋体; font-size: 12pt">负责加载</span><span style="font-size: 12pt">EAR</span><span style="font-family: 宋体; font-size: 12pt">里面所有的</span><span style="font-size: 12pt">EJB jar</span><span style="font-family: 宋体; font-size: 12pt">。因此，</span><span style="font-size: 12pt">EAR</span><span style="font-family: 宋体; font-size: 12pt">中的</span><span style="font-size: 12pt">EJB</span><span style="font-family: 宋体; font-size: 12pt">彼此之间可以看到对方</span></p>
<p style="text-align: left; text-indent: -23.3pt; margin-left: 45pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt">EJB Class Loader (2) </span><span style="font-family: 宋体; font-size: 12pt">下有多个</span><span style="font-size: 12pt">WAR Class Loader (2) </span><span style="font-family: 宋体; font-size: 12pt">实例。每个实例负责加载</span><span style="font-size: 12pt">EAR</span><span style="font-family: 宋体; font-size: 12pt">里面的一个</span><span style="font-size: 12pt">WAR</span><span style="font-family: 宋体; font-size: 12pt">。所以，</span><span style="font-size: 12pt">EAR</span><span style="font-family: 宋体; font-size: 12pt">中的</span><span style="font-size: 12pt">WAR</span><span style="font-family: 宋体; font-size: 12pt">彼此之间看不到对方</span></p>
<p style="text-align: left; text-indent: -23.3pt; margin-left: 45pt; tab-stops: list 27.0pt" class="MsoNormal" align="left"><span style="font-family: Wingdings; font-size: 12pt">l<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体; font-size: 12pt">根据继承链规则，</span><span style="font-size: 12pt">WAR</span><span style="font-family: 宋体; font-size: 12pt">可以看到所有的</span><span style="font-size: 12pt">EJB</span><span style="font-family: 宋体; font-size: 12pt">及</span><span style="font-size: 12pt">APP-INF</span><span style="font-family: 宋体; font-size: 12pt">下的所有类。</span><span style="font-size: 12pt"> EJB</span><span style="font-family: 宋体; font-size: 12pt">可以看到</span><span style="font-size: 12pt">APP-INF</span><span style="font-family: 宋体; font-size: 12pt">下的所有类，但反之则不可以</span></p>
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">虽然称为类加载器，但并不意味着只能用来加载</span><span style="font-size: 12pt">Class</span><span style="font-family: 宋体; font-size: 12pt">，我们还可以利用它来查找图片和配置文件等资源。比如，我们经常使用</span><span style="font-size: 12pt">getClass().getResourceAsStream(name)</span><span style="font-family: 宋体; font-size: 12pt">来查找配置文件。同样，查找其它资源文件的方式和上面一样，也会先请求父</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">来负责查找。</span></p>
<p style="text-align: left" class="MsoNormal" align="left"><span style="font-family: 宋体; font-size: 12pt">这里，我们只简单介绍了</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">对于类的查找，而关于</span><span style="font-size: 12pt">Class Loader</span><span style="font-family: 宋体; font-size: 12pt">的具体加载、校验和初始化的过程，感兴趣的朋友可以参考《深入</span><span style="font-size: 12pt">Java</span><span style="font-family: 宋体; font-size: 12pt">虚拟机》</span></p>
 <img src ="http://www.blogjava.net/zhvfeng/aggbug/329078.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhvfeng/" target="_blank">天快黑了</a> 2010-08-17 10:47 <a href="http://www.blogjava.net/zhvfeng/archive/2010/08/17/329078.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>谁能帮忙解释一下为什么这个程序会死锁？</title><link>http://www.blogjava.net/zhvfeng/archive/2010/08/04/327956.html</link><dc:creator>天快黑了</dc:creator><author>天快黑了</author><pubDate>Wed, 04 Aug 2010 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/zhvfeng/archive/2010/08/04/327956.html</guid><wfw:comment>http://www.blogjava.net/zhvfeng/comments/327956.html</wfw:comment><comments>http://www.blogjava.net/zhvfeng/archive/2010/08/04/327956.html#Feedback</comments><slash:comments>23</slash:comments><wfw:commentRss>http://www.blogjava.net/zhvfeng/comments/commentRss/327956.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhvfeng/services/trackbacks/327956.html</trackback:ping><description><![CDATA[<p>&#160;大家不用关心程序实际逻辑是否正确，只是好奇，为什么这个程序会hang住不运行了？而且CPU会占用100%</p>
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&#160;java.util.HashMap;<br />
<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&#160;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&#160;TestLock&#160;{<br />
<br />
</span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&#160;HashMap&#160;map&#160;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&#160;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&#160;HashMap();<br />
<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&#160;TestLock()&#160;{<br />
Thread&#160;t1&#160;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&#160;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&#160;Thread()&#160;{<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&#160;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&#160;run()&#160;{<br />
</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&#160;i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&#160;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">50000</span><span style="color: #000000; ">;&#160;i</span><span style="color: #000000; ">++</span><span style="color: #000000; ">)&#160;{<br />
map.put(</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&#160;Integer(i),&#160;i);<br />
}<br />
System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">t1&#160;over</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
}<br />
};<br />
<br />
Thread&#160;t2&#160;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&#160;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&#160;Thread()&#160;{<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&#160;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&#160;run()&#160;{<br />
</span><span style="color: #0000FF; ">for</span><span style="color: #000000; ">(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&#160;i</span><span style="color: #000000; ">=</span><span style="color: #000000; ">0</span><span style="color: #000000; ">;&#160;i</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">50000</span><span style="color: #000000; ">;&#160;i</span><span style="color: #000000; ">++</span><span style="color: #000000; ">)&#160;{<br />
map.put(</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&#160;Integer(i),&#160;i);<br />
}<br />
<br />
System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">t2&#160;over</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
}<br />
};<br />
<br />
<br />
t1.start();<br />
t2.start();<br />
<br />
}<br />
<br />
<br />
</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&#160;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&#160;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&#160;main(String[]&#160;args)&#160;{&#160;&#160;&#160;&#160;<br />
</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&#160;TestLock();<br />
}<br />
}<br />
</span></div>
<br />
<br />
Dump thread会看到，程序hang到：<br />
<br />
<p><font style="background-color: #c0c0c0">"Thread-1" prio=6 tid=0x00c70bd8 nid=0x914 runnable [0x02ebf000..0x02ebfc68]<br />
at java.util.HashMap.put(HashMap.java:420)<br />
at TestLock$2.run(TestLock.java:20)</font></p>
<p><font style="background-color: #c0c0c0">"Thread-0" prio=6 tid=0x00c70a50 nid=0x578 runnable [0x02e7f000..0x02e7fb68]<br />
at java.util.HashMap.put(HashMap.java:420)<br />
at TestLock$1.run(TestLock.java:11)<br />
</font></p>
 <img src ="http://www.blogjava.net/zhvfeng/aggbug/327956.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhvfeng/" target="_blank">天快黑了</a> 2010-08-04 17:40 <a href="http://www.blogjava.net/zhvfeng/archive/2010/08/04/327956.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>另类NoClassDefFoundError</title><link>http://www.blogjava.net/zhvfeng/archive/2010/07/29/327446.html</link><dc:creator>天快黑了</dc:creator><author>天快黑了</author><pubDate>Thu, 29 Jul 2010 07:54:00 GMT</pubDate><guid>http://www.blogjava.net/zhvfeng/archive/2010/07/29/327446.html</guid><wfw:comment>http://www.blogjava.net/zhvfeng/comments/327446.html</wfw:comment><comments>http://www.blogjava.net/zhvfeng/archive/2010/07/29/327446.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhvfeng/comments/commentRss/327446.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhvfeng/services/trackbacks/327446.html</trackback:ping><description><![CDATA[通常NoClassDefFoundError产生的原因都是由于用到的class在CLASSPATH中找不到。<br />
<br />
还有下面一种另类的NoClassDefFoundError：<br />
1. Class A 调用 Class B<br />
2. JVM尝试加载Class B，并执行Class B的静态块<br />
3. Class B的静态块内抛出RuntimeException，从而导致JVM加载Class B失败<br />
4. 之后，任何类只要调用Class B，就会出现NoClassDefFoundError<br />
<br />
大家可以运行下面的例子试一下:<br />
<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #008080">1</span>&nbsp;<span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;B&nbsp;<br />
</span><span style="color: #008080">2</span>&nbsp;<span style="color: #000000">{<br />
</span><span style="color: #008080">3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;{<br />
</span><span style="color: #008080">4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
</span><span style="color: #008080">5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s.substring(</span><span style="color: #000000">0</span><span style="color: #000000">);<br />
</span><span style="color: #008080">6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">7</span>&nbsp;<span style="color: #000000">}</span></div>
<br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><span style="color: #008080">&nbsp;1</span>&nbsp;<span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;A&nbsp;<br />
</span><span style="color: #008080">&nbsp;2</span>&nbsp;<span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;3</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;<br />
</span><span style="color: #008080">&nbsp;4</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080">&nbsp;5</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;6</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080">&nbsp;7</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;B&nbsp;b&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;B();&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;8</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">&nbsp;9</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(Throwable&nbsp;e)<br />
</span><span style="color: #008080">10</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080">11</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
</span><span style="color: #008080">12</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">13</span>&nbsp;<span style="color: #000000"><br />
</span><span style="color: #008080">14</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000"><br />
</span><span style="color: #008080">15</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080">16</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;B&nbsp;b&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;B();&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">17</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">18</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(Throwable&nbsp;e)<br />
</span><span style="color: #008080">19</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080">20</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
</span><span style="color: #008080">21</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">22</span>&nbsp;<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080">23</span>&nbsp;<span style="color: #000000">}</span></div>
  <img src ="http://www.blogjava.net/zhvfeng/aggbug/327446.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhvfeng/" target="_blank">天快黑了</a> 2010-07-29 15:54 <a href="http://www.blogjava.net/zhvfeng/archive/2010/07/29/327446.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Socket Programming Considerations (2)</title><link>http://www.blogjava.net/zhvfeng/archive/2010/07/28/327281.html</link><dc:creator>天快黑了</dc:creator><author>天快黑了</author><pubDate>Wed, 28 Jul 2010 01:23:00 GMT</pubDate><guid>http://www.blogjava.net/zhvfeng/archive/2010/07/28/327281.html</guid><wfw:comment>http://www.blogjava.net/zhvfeng/comments/327281.html</wfw:comment><comments>http://www.blogjava.net/zhvfeng/archive/2010/07/28/327281.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zhvfeng/comments/commentRss/327281.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhvfeng/services/trackbacks/327281.html</trackback:ping><description><![CDATA[&nbsp;
<h2 style="text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt"><span style="line-height: 173%; font-size: 12pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 173%; font-size: 12pt">Socket ack (acknowledgement)</span></h2>
<p style="margin-left: 21pt" class="MsoNormal">Socket ack<span style="font-family: 宋体">是指当</span>socket<span style="font-family: 宋体">接收到数据之后，发送一个</span>ack<span style="font-family: 宋体">字符串</span>(<span style="font-family: 宋体">比如</span>$ACK)<span style="font-family: 宋体">给</span>socket<span style="font-family: 宋体">发送方。这样，</span>socket<span style="font-family: 宋体">发送方可以根据是否收到了</span>ack<span style="font-family: 宋体">判断对方是否收到了数据。</span></p>
<p style="margin-left: 21pt" class="MsoNormal">Socket ack<span style="font-family: 宋体">是显示的在应用程序中加入的一种通讯协议。如果不使用</span>ack<span style="font-family: 宋体">，在</span>socket<span style="font-family: 宋体">通讯中，可能会丢失数据。</span></p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">比如，</span>socket client<span style="font-family: 宋体">要连续的给</span>socket server<span style="font-family: 宋体">发送</span>100<span style="font-family: 宋体">条消息。如果我们在</span>server<span style="font-family: 宋体">收到第</span>50<span style="font-family: 宋体">条消息的时候，强行</span>kill<span style="font-family: 宋体">了</span>server<span style="font-family: 宋体">。那么查询</span>client<span style="font-family: 宋体">端发送的</span>log<span style="font-family: 宋体">，可能</span>client<span style="font-family: 宋体">端成功发送了</span>51<span style="font-family: 宋体">条。只有当</span>client<span style="font-family: 宋体">端发送第</span>52<span style="font-family: 宋体">条消息的时候才遇到异常。这样第</span>51<span style="font-family: 宋体">条消息就丢失了。</span></p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">所以为了确保数据传输的准确性，我们可以引入</span>ack<span style="font-family: 宋体">协议。有时我们不仅要确保</span>server<span style="font-family: 宋体">不但收到了数据，而且还要保证</span>server<span style="font-family: 宋体">成功处理了数据。这时，可以等</span>server<span style="font-family: 宋体">成功处理完数据之后，再给</span>client<span style="font-family: 宋体">发</span>ack<span style="font-family: 宋体">。</span></p>
<h2 style="text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt"><span style="line-height: 173%; font-size: 12pt">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 173%; font-size: 12pt">Socket Keep Alive</span></h2>
<p style="margin-left: 21pt" class="MsoNormal">Socket<span style="font-family: 宋体">连接像数据库连接一样，属于重量型资源。如果我们频繁的创建</span>socket<span style="font-family: 宋体">、发送</span>/<span style="font-family: 宋体">接收数据、关闭</span>socket<span style="font-family: 宋体">，那么会有很大一部分时间浪费在</span>socket<span style="font-family: 宋体">的创建和关闭上。</span></p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">所以，如果我们经常需要与同一个</span>socket<span style="font-family: 宋体">地址发送</span>/<span style="font-family: 宋体">接收数据时，应该考虑只创建一次</span>socket<span style="font-family: 宋体">，然后一直使用这个</span>socket<span style="font-family: 宋体">对象发送</span>/<span style="font-family: 宋体">接收数据。</span></p>
<h2 style="text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt"><span style="line-height: 173%; font-size: 12pt">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 173%; font-size: 12pt">Heartbeat</span></h2>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">通常，我们会设置</span>socket<span style="font-family: 宋体">的</span>receive timeout<span style="font-family: 宋体">。这样，如果我们一直打开着</span>socket (keep alive)<span style="font-family: 宋体">，</span> <span style="font-family: 宋体">而很长时间又没有数据通讯，</span>socket<span style="font-family: 宋体">接收方就会</span>timeout<span style="font-family: 宋体">，最终导致打开的连接坏掉。</span></p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">如果很长时间没有数据通讯，防火墙或代理服务器也可能会关闭打开的</span>socket<span style="font-family: 宋体">连接。</span></p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">所以为了保证打开的</span>socket<span style="font-family: 宋体">连接一直可用，如果一段时间没有数据进行通讯（或指定一个时间间隔），我们可以显示的发送一个</span>heartbeat<span style="font-family: 宋体">消息</span>(<span style="font-family: 宋体">比如</span>: $HRT)<span style="font-family: 宋体">给对方，从而保证连接不会被异常关闭。</span></p>
<h2 style="text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt"><span style="line-height: 173%; font-size: 12pt">4.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 173%; font-size: 12pt">Socket Close</span></h2>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">每一个socket</span><span style="font-family: 宋体">对象会持有一个socket descriptor (</span><span style="font-family: 宋体">其实就是file descriptor)</span><span style="font-family: 宋体">，操作系统对于socket descriptor</span><span style="font-family: 宋体">有一个最大限制</span><span style="font-family: 宋体">。因此当</span>socket<span style="font-family: 宋体">不再使用时，一定要记得关闭，即使</span>socket<span style="font-family: 宋体">连接失败或出现异常，只要</span>socket<span style="font-family: 宋体">对象不为</span>null<span style="font-family: 宋体">，一定要记得关闭。</span></p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">下面图显示了，当</span>socket<span style="font-family: 宋体">关闭时，</span>socket<span style="font-family: 宋体">的状态变化</span>(socket<span style="font-family: 宋体">状态可以通过</span>netstat<span style="font-family: 宋体">命令查看</span>)<span style="font-family: 宋体">。更详细的解释，可以</span>google<span style="font-family: 宋体">一下。<br />
<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/zhvfeng/image001.png" /><br />
</span></p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">当主动一方调用</span>close(<span style="font-family: 宋体">先调用</span>close)<span style="font-family: 宋体">时的状态变化</span>: </p>
<p style="margin-left: 21pt" class="MsoNormal">ESTABLISHED -&gt; FIN_WAIT_1-&gt; FIN_WAIT_2 -&gt; TIME_WAIT -&gt; CLOSED</p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">当被动一方调用</span>close(<span style="font-family: 宋体">后调用</span>close)<span style="font-family: 宋体">时的状态变化</span>:</p>
<p style="margin-left: 21pt" class="MsoNormal">ESTABLISHED -&gt; CLOSE_WAIT -&gt; LAST_ACK -&gt; CLOSED</p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">通常，</span>TIME_WAIT <span style="font-family: 宋体">是正常状态，过一段时间</span>(2MSL, 1<span style="font-family: 宋体">到</span>4<span style="font-family: 宋体">分钟</span>)<span style="font-family: 宋体">就会自动消失</span>.</p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">我们需要特别注意</span>CLOSE_WAIT <span style="font-family: 宋体">状态：</span></p>
<p style="text-indent: -20.5pt; margin-left: 41.5pt; tab-stops: list 41.5pt" class="MsoNormal">1．<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">如果很长时间才消失，表明</span>socket server<span style="font-family: 宋体">处理太慢，很多</span>client<span style="font-family: 宋体">已经连接到</span>server<span style="font-family: 宋体">，发送完数据并</span>close<span style="font-family: 宋体">了。</span></p>
<p style="text-indent: -20.5pt; margin-left: 41.5pt; tab-stops: list 41.5pt" class="MsoNormal">2．<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">如果一直也不消失，表明有</span>socket<span style="font-family: 宋体">没有正常</span>close (<span style="font-family: 宋体">对方已经</span>close<span style="font-family: 宋体">了</span>)</p>
<h2 style="text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt"><span style="line-height: 173%; font-size: 12pt">5.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 173%; font-size: 12pt">SO_REUSEADDR Option</span></h2>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">当</span>socket<span style="font-family: 宋体">主动调用</span>close<span style="font-family: 宋体">的时候，从上面可以知道，它最终会进入</span>TIME_WAIT <span style="font-family: 宋体">状态，需要过</span>1<span style="font-family: 宋体">到</span>4<span style="font-family: 宋体">分钟，才能完全</span>close<span style="font-family: 宋体">。</span></p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">当</span>socket<span style="font-family: 宋体">处于</span>TIME_WAIT <span style="font-family: 宋体">状态时，它仍然占用正在使用的</span>IP/PORT<span style="font-family: 宋体">。这样，如果我们的程序</span>(<span style="font-family: 宋体">比如</span>socket server)<span style="font-family: 宋体">使用了一个固定的</span>IP/PORT<span style="font-family: 宋体">，当</span>socket<span style="font-family: 宋体">处于</span>TIME_WAIT <span style="font-family: 宋体">状态时，程序将不能立即重启，会出现端口占用错误。</span></p>
<p style="margin-left: 21pt" class="MsoNormal">Socket<span style="font-family: 宋体">提供了一个</span>setReuseAddress()<span style="font-family: 宋体">方法，可以设置当</span>socket<span style="font-family: 宋体">处于</span>TIME_WAIT <span style="font-family: 宋体">状态时，是否允许其它进程绑定这个端口。</span></p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">如果我们正在开发</span>socket server<span style="font-family: 宋体">，一定要记得调用</span>ServerSocket.setReuseAddress(true).</p>
<p style="margin-left: 21pt" class="MsoNormal">Client socket<span style="font-family: 宋体">也有这个方法，而且有时可能需要指明</span>client<span style="font-family: 宋体">连接</span>server<span style="font-family: 宋体">时所使用的本地</span>IP/PORT(<span style="font-family: 宋体">一般不用指明，系统会随机选择一个</span>PORT)<span style="font-family: 宋体">。但实际测试，在</span>client socket<span style="font-family: 宋体">上设置这个方法在</span>Windows<span style="font-family: 宋体">和</span>Solaris<span style="font-family: 宋体">下并不起作用。当</span>socket<span style="font-family: 宋体">处于</span>TIME_WAIT <span style="font-family: 宋体">状态时，重启</span>client<span style="font-family: 宋体">仍然出现端口占用错误。上网搜索了很长时间，很多人都碰到了这个问题，可能是操作系统底层</span>socket<span style="font-family: 宋体">实现问题。因为测试使用</span>C<span style="font-family: 宋体">语言开发的</span>socket client<span style="font-family: 宋体">，同样也有这个错误。有人说</span>LINUX<span style="font-family: 宋体">下好用，还有就是可以尝试修改</span>tcp_time_wait_interval<span style="font-family: 宋体">来减小</span>TIME_WAIT<span style="font-family: 宋体">等待时间</span></p>
 <img src ="http://www.blogjava.net/zhvfeng/aggbug/327281.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhvfeng/" target="_blank">天快黑了</a> 2010-07-28 09:23 <a href="http://www.blogjava.net/zhvfeng/archive/2010/07/28/327281.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Socket Programming Considerations (1)</title><link>http://www.blogjava.net/zhvfeng/archive/2010/07/26/327114.html</link><dc:creator>天快黑了</dc:creator><author>天快黑了</author><pubDate>Mon, 26 Jul 2010 01:31:00 GMT</pubDate><guid>http://www.blogjava.net/zhvfeng/archive/2010/07/26/327114.html</guid><wfw:comment>http://www.blogjava.net/zhvfeng/comments/327114.html</wfw:comment><comments>http://www.blogjava.net/zhvfeng/archive/2010/07/26/327114.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zhvfeng/comments/commentRss/327114.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhvfeng/services/trackbacks/327114.html</trackback:ping><description><![CDATA[第一次开博，第一次写文章。文笔不好，只是记录一下个人心得。<br />
<br />
最近一直在做Socket程序，这里把一些Socket程序的注意事项总结一下。今天先说说Socket中的Timeout，其它的下次补全。<br />
<br />
<br />
<h2 style="text-indent: -21pt; margin-left: 21pt; tab-stops: list 21.0pt"><span style="line-height: 173%; font-size: 12pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="line-height: 173%; font-size: 12pt">Socket Timeout</span></h2>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">写</span>Socket<span style="font-family: 宋体">程序的时候需要注意设置下面的</span>timeout<span style="font-family: 宋体">，避免对方没有响应的时候，导致</span>Socket<span style="font-family: 宋体">程序挂起或等待时间过长</span></p>
<h3 style="line-height: normal; text-indent: -1cm; margin-left: 49.6pt; tab-stops: list 49.6pt"><span style="font-size: 12pt">1.1<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt">&nbsp;Accept Timeout</span></h3>
<p style="margin-left: 21pt" class="MsoNormal">Accept timeout <span style="font-family: 宋体">仅对</span>ServerSocket<span style="font-family: 宋体">有用。</span>ServerSocket <span style="font-family: 宋体">使用</span>accept()<span style="font-family: 宋体">方法来监听客户端</span>Socket<span style="font-family: 宋体">的连接。</span></p>
<p style="text-indent: 0.05pt; margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">默认，</span>ServerSocket.accept() <span style="font-family: 宋体">方法会一直阻塞直到有客户端来连接</span><span style="font-family: 宋体">。通常，我们不需要设置</span>accept timeout.</p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">但有时候特殊情况，还是要考虑设置</span>accept timeout. </p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">比如</span>: <span style="font-family: 宋体">程序</span>A<span style="font-family: 宋体">给程序</span>B<span style="font-family: 宋体">发了一个</span>JMS<span style="font-family: 宋体">消息，然后程序</span>A<span style="font-family: 宋体">启动一个</span>Socket Server<span style="font-family: 宋体">，想通过</span>socket<span style="font-family: 宋体">等待接收程序</span>B<span style="font-family: 宋体">的返回消息。如果不设置</span>accept timeout, <span style="font-family: 宋体">并且程序</span>B<span style="font-family: 宋体">因为某些原因一直不能连接</span>Socket Server<span style="font-family: 宋体">，最终会导致程序</span>A<span style="font-family: 宋体">挂起。</span></p>
<p style="margin-left: 21pt" class="MsoNormal">Accept Timeout<span style="font-family: 宋体">可以这样设置：</span></p>
<p style="margin-left: 21pt" class="MsoNormal">ServerSocket serverSocket = new ServerSocket(5555);</p>
<p style="margin-left: 21pt" class="MsoNormal">serverSocket.setSoTimeout(5000); // in milliseconds</p>
<p style="margin-left: 21pt" class="MsoNormal">while (true) {</p>
<p style="margin-left: 21pt" class="MsoNormal">&nbsp;&nbsp;&nbsp; Socket socket = serverSocket.accept();</p>
<p style="margin-left: 21pt" class="MsoNormal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;</p>
<p style="margin-left: 21pt" class="MsoNormal">}</p>
<h3 style="line-height: normal; text-indent: -17.85pt; margin-left: 38.85pt; tab-stops: list 49.6pt"><span style="font-size: 12pt">1.2<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt">&nbsp;Connect Timeout</span></h3>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">当</span>Client<span style="font-family: 宋体">端连接</span>Server<span style="font-family: 宋体">端的时候，可以指定</span>Connect Timeout</p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">如果没有指定，会使用操作系统的默认值</span>:</p>
<div align="center">
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" class="MsoTableGrid" border="1" cellspacing="0" cellpadding="0">
    <tbody>
        <tr style="height: 13.85pt">
            <td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 174pt; padding-right: 5.4pt; background: #e0e0e0; height: 13.85pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="314">
            <p><strong>OS</strong></p>
            </td>
            <td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 174pt; padding-right: 5.4pt; background: #e0e0e0; height: 13.85pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="314">
            <p><strong>Default TCP timeout</strong></p>
            </td>
        </tr>
        <tr style="height: 13.85pt">
            <td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 174pt; padding-right: 5.4pt; height: 13.85pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="314">
            <p>BSD</p>
            </td>
            <td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 174pt; padding-right: 5.4pt; height: 13.85pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="314">
            <p>75 seconds</p>
            </td>
        </tr>
        <tr style="height: 13.85pt">
            <td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 174pt; padding-right: 5.4pt; height: 13.85pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="314">
            <p>Linux</p>
            </td>
            <td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 174pt; padding-right: 5.4pt; height: 13.85pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="314">
            <p>189 seconds</p>
            </td>
        </tr>
        <tr style="height: 13.3pt">
            <td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 174pt; padding-right: 5.4pt; height: 13.3pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="314">
            <p>Solaris</p>
            </td>
            <td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 174pt; padding-right: 5.4pt; height: 13.3pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="314">
            <p>225 seconds</p>
            </td>
        </tr>
        <tr style="height: 14.4pt">
            <td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 174pt; padding-right: 5.4pt; height: 14.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="314">
            <p>Windows XP</p>
            </td>
            <td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 174pt; padding-right: 5.4pt; height: 14.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="314">
            <p>21 seconds</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p style="margin-left: 21pt" class="MsoNormal">Connect Timeout<span style="font-family: 宋体">可以这样设置：</span></p>
<p style="margin-left: 21pt" class="MsoNormal">SocketAddress socketAddress = new InetSocketAddress(host, port);</p>
<p style="margin-left: 21pt" class="MsoNormal">socket = new Socket();</p>
<p style="margin-left: 21pt" class="MsoNormal">socket.connect(socketAddress, connectTimeout);</p>
<h3 style="line-height: normal; text-indent: -17.85pt; margin-left: 38.85pt; tab-stops: list 49.6pt"><span style="font-size: 12pt">1.3<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt">&nbsp;Receive Timeout</span></h3>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">当</span>socket<span style="font-family: 宋体">从另一方接收数据时，可以设置</span>Receive Timeout</p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">默认没有</span>timeout<span style="font-family: 宋体">，</span>socket<span style="font-family: 宋体">会一直阻塞直到有数据可读取。</span></p>
<p style="margin-left: 21pt" class="MsoNormal">Receive Timeout<span style="font-family: 宋体">可以这样设置：</span></p>
<p style="margin-left: 21pt" class="MsoNormal">Socket socket = new Socket(host, port);</p>
<p style="margin-left: 21pt" class="MsoNormal">socket.setSoTimeout(timeout);</p>
<h3 style="line-height: normal; text-indent: -17.85pt; margin-left: 38.85pt; tab-stops: list 49.6pt"><span style="font-size: 12pt">1.4<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 12pt">&nbsp;Send Timeout</span></h3>
<p style="margin-left: 21pt" class="MsoNormal">Send Timeout<span style="font-family: 宋体">是</span>socket<span style="font-family: 宋体">给另一方发送数据时使用的。</span></p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">不过</span>Java<span style="font-family: 宋体">里没有办法设置</span>Send Timeout.</p>
<p style="margin-left: 21pt" class="MsoNormal"><span style="font-family: 宋体">当然，</span>socket<span style="font-family: 宋体">发送数据的时候，会首先发送到本机</span>OS<span style="font-family: 宋体">的一个</span>buffer<span style="font-family: 宋体">内。一般只要一次发送的数据不是很大，即使对方挂起或暂时不能接收数据，也不会导致发送方挂起。</span></p>
<br />
       <img src ="http://www.blogjava.net/zhvfeng/aggbug/327114.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhvfeng/" target="_blank">天快黑了</a> 2010-07-26 09:31 <a href="http://www.blogjava.net/zhvfeng/archive/2010/07/26/327114.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>