﻿<?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-Jelver'Sky-文章分类-Java Basic/Lucene/开源资料</title><link>http://www.blogjava.net/jelver/category/7676.html</link><description>“一直很多人说我是天才，但我却相信这个世界没有天才。如果没有卓越的努力和娴熟的球性，你永远不会踢出精彩的足球。我从来不会低估努力的重要性，而这正是我对自己的要求。”
----------------------------------------------------------------------------罗纳尔迪尼奥(Ronaldinho)--------
“不要叫我神童！我不是神童！我所获得的一切成就，都是我用汗水和刻苦训练换来的！” --------------------------丁俊辉（中国斯诺克公开赛冠军）---
</description><language>zh-cn</language><lastBuildDate>Tue, 13 May 2008 22:24:04 GMT</lastBuildDate><pubDate>Tue, 13 May 2008 22:24:04 GMT</pubDate><ttl>60</ttl><item><title>HttpURLConnection常用处理方式</title><link>http://www.blogjava.net/jelver/articles/199472.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Fri, 09 May 2008 05:25:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/199472.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/199472.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/199472.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/199472.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/199472.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: /**//*&nbsp;*&nbsp;Classname&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;GameSoapProcessor&nbsp;*&nbsp;Create&nbsp;Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;2008-5-7&nbsp;*/package&nbsp;cn....&nbsp;&nbsp;<a href='http://www.blogjava.net/jelver/articles/199472.html'>阅读全文</a><img src ="http://www.blogjava.net/jelver/aggbug/199472.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2008-05-09 13:25 <a href="http://www.blogjava.net/jelver/articles/199472.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java分页</title><link>http://www.blogjava.net/jelver/articles/198579.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Mon, 05 May 2008 14:18:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/198579.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/198579.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/198579.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/198579.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/198579.html</trackback:ping><description><![CDATA[定义两个vector，一个为储存查询所有记录的totalv,另一个储存当前页的记录currentpagev; <br />
总的记录数：int totalsize = totalv.getsize(); <br />
每页显示的记录数：int countperpage; <br />
总页数：int totalpagenum = totalsize/countperpage; <br />
//如果总的记录数和每页记录数的余数大于零， <br />
//那么总的页数为他们的整除结果加一 <br />
if (totalsize%countperpage &gt; 0 ){ <br />
totalpagenum = totalsize/countperpage + 1; <br />
} <br />
当前的页数：pagenum； <br />
<br />
for (int j = 0;j&lt;totalv.size();j++){ <br />
//分页，根据当前的页数和每页显示的记录数从totalv中取出记录 <br />
//往currentpagev中添加记录； <br />
//如果当前记录在(当前页码-1)*每页显示记录数（包括等于） <br />
//和 当前页码*每页显示记录数（不包括等于）之间的时候； <br />
//就属于该页的数据 <br />
if ( (j &gt;= (pagenum - 1) * countperpage) &amp;&amp; (j &lt; pagenum * countperpage)) { <br />
currentpagev.addelement(totalv.get(j)); <br />
} <br />
//当currentpagev记录数等于每页显示记录数， <br />
//停止往currentpagev中添加记录 <br />
if (currentpagev.size() == countperpage) { <br />
break; <br />
} <br />
} <br />
那么，当前页中显示的记录，就是currentpagev中的记录。 
<img src ="http://www.blogjava.net/jelver/aggbug/198579.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2008-05-05 22:18 <a href="http://www.blogjava.net/jelver/articles/198579.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在java中理解“回调函数” </title><link>http://www.blogjava.net/jelver/articles/189086.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Thu, 27 Mar 2008 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/189086.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/189086.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/189086.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/189086.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/189086.html</trackback:ping><description><![CDATA[<p><font face="Arial">所谓回调，就是客户程序C调用服务程序S中的某个函数A，然后S又在某个时候反过来调用C中的某个函数B，对于C来说，这个B便叫做回调函数。<br />
<br />
一般说来，C不会自己调用B，C提供B的目的就是让S来调用它，而且是C不得不提供。由于S并不知道C提供的B叫甚名谁，所以S会约定B的接口规范（函数原型），然后由C提前通过S的一个函数R告诉S自己将要使用B函数，这个过程称为回调函数的注册，R称为注册函数。<br />
<br />
下面举个通俗的例子：<br />
<br />
某天，我打电话向你请教问题，当然是个难题，:)，你一时想不出解决方法，我又不能拿着电话在那里傻等，于是我们约定：等你想出办法后打手机通知我，这样，我就挂掉电话办其它事情去了。过了XX分钟，我的手机响了，你兴高采烈的说问题已经搞定，应该如此这般处理。故事到此结束。<br />
<br />
这个例子说明了&#8220;异步+回调&#8221;的编程模式。其中，你后来打手机告诉我结果便是一个&#8220;回调&#8221;过程；我的手机号码必须在以前告诉你，这便是注册回调函数；我的手机号码应该有效并且手机能够接收到你的呼叫，这是回调函数必须符合接口规范。</font></p>
<br />
<p><font face="Arial">如果你还不太清楚看看这段描述合和代码：<br />
<br />
声明一个接口，另外一个类有方法里面有个参数以是这个接口类型的，而后在另外类中实现这个接口(java中多用的是匿名内部类)，而且以这个匿名的类生成的对象为参数传到上面提到类中，而后实现回调.......这种用法可以参考java里面常用到的数据库操作所用到的几个接口.....<br />
<br />
注：匿名内部类 的说明可以见 <a href="http://dev.csdn.net/author/CMTobby/339cbab3897f4106bed2fe2ecd75470a.html" target="_blank">http://dev.csdn.net/author/CMTobby/339cbab3897f4106bed2fe2ecd75470a.html</a></font></p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #008000">//</span><span style="color: #008000">声明一个接口</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000"><br />
<img id="Codehighlighter1_40_63_Open_Image" onclick="this.style.display='none'; Codehighlighter1_40_63_Open_Text.style.display='none'; Codehighlighter1_40_63_Closed_Image.style.display='inline'; Codehighlighter1_40_63_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_40_63_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_40_63_Closed_Text.style.display='none'; Codehighlighter1_40_63_Open_Image.style.display='inline'; Codehighlighter1_40_63_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">interface</span><span style="color: #000000">&nbsp;ICallBack()</span><span id="Codehighlighter1_40_63_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_40_63_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;postExec();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">另外一个类有方法里面有个参数以是这个接口类型的</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000"><br />
<img id="Codehighlighter1_120_309_Open_Image" onclick="this.style.display='none'; Codehighlighter1_120_309_Open_Text.style.display='none'; Codehighlighter1_120_309_Closed_Image.style.display='inline'; Codehighlighter1_120_309_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_120_309_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_120_309_Closed_Text.style.display='none'; Codehighlighter1_120_309_Open_Image.style.display='inline'; Codehighlighter1_120_309_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;FooBar..</span><span id="Codehighlighter1_120_309_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_120_309_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;ICallBack&nbsp;callBack;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_199_233_Open_Image" onclick="this.style.display='none'; Codehighlighter1_199_233_Open_Text.style.display='none'; Codehighlighter1_199_233_Closed_Image.style.display='inline'; Codehighlighter1_199_233_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_199_233_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_199_233_Closed_Text.style.display='none'; Codehighlighter1_199_233_Open_Image.style.display='inline'; Codehighlighter1_199_233_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;setCallBack(ICallBack&nbsp;callBack)</span><span id="Codehighlighter1_199_233_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_199_233_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.callBack</span><span style="color: #000000">=</span><span style="color: #000000">callBack;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_257_300_Open_Image" onclick="this.style.display='none'; Codehighlighter1_257_300_Open_Text.style.display='none'; Codehighlighter1_257_300_Closed_Image.style.display='inline'; Codehighlighter1_257_300_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_257_300_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_257_300_Closed_Text.style.display='none'; Codehighlighter1_257_300_Open_Image.style.display='inline'; Codehighlighter1_257_300_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;doSth()</span><span id="Codehighlighter1_257_300_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_257_300_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />.<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;callBack.postExec();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;..<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">---------------------------------------</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />回调的实现<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_377_583_Open_Image" onclick="this.style.display='none'; Codehighlighter1_377_583_Open_Text.style.display='none'; Codehighlighter1_377_583_Closed_Image.style.display='inline'; Codehighlighter1_377_583_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_377_583_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_377_583_Closed_Text.style.display='none'; Codehighlighter1_377_583_Open_Image.style.display='inline'; Codehighlighter1_377_583_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Test</span><span id="Codehighlighter1_377_583_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_377_583_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_421_580_Open_Image" onclick="this.style.display='none'; Codehighlighter1_421_580_Open_Text.style.display='none'; Codehighlighter1_421_580_Closed_Image.style.display='inline'; Codehighlighter1_421_580_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_421_580_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_421_580_Closed_Text.style.display='none'; Codehighlighter1_421_580_Open_Image.style.display='inline'; Codehighlighter1_421_580_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&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)</span><span id="Codehighlighter1_421_580_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_421_580_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FooBar&nbsp;foo</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;FooBar();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_491_572_Open_Image" onclick="this.style.display='none'; Codehighlighter1_491_572_Open_Text.style.display='none'; Codehighlighter1_491_572_Closed_Image.style.display='inline'; Codehighlighter1_491_572_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_491_572_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_491_572_Closed_Text.style.display='none'; Codehighlighter1_491_572_Open_Image.style.display='inline'; Codehighlighter1_491_572_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo.setCallBack(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ICallBack()</span><span id="Codehighlighter1_491_572_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_491_572_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_524_564_Open_Image" onclick="this.style.display='none'; Codehighlighter1_524_564_Open_Text.style.display='none'; Codehighlighter1_524_564_Closed_Image.style.display='inline'; Codehighlighter1_524_564_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_524_564_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_524_564_Closed_Text.style.display='none'; Codehighlighter1_524_564_Open_Image.style.display='inline'; Codehighlighter1_524_564_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;postExec()</span><span id="Codehighlighter1_524_564_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_524_564_Open_Text"><span style="color: #000000">{System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">method&nbsp;executed.</span><span style="color: #000000">"</span><span style="color: #000000">);}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<img src ="http://www.blogjava.net/jelver/aggbug/189086.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2008-03-27 17:40 <a href="http://www.blogjava.net/jelver/articles/189086.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网络编程中的异步编程</title><link>http://www.blogjava.net/jelver/articles/189060.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Thu, 27 Mar 2008 08:58:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/189060.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/189060.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/189060.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/189060.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/189060.html</trackback:ping><description><![CDATA[该文章对编写客户服务器应用的java程序员有所帮助,可以解决程序在对方出现故障的时候继续稳定运行.<br />
　　目前java平台已经广泛应用于各类客户/服务器系统中，在实际编程中，往往需要网络的异步处理。比如客户程序，如果客户程序运行先于服务程序，则客户程序则需要在服务程序启动后再自动连接服务程序；在客户程序运行中如果服务程序中途停止，则也需要在不停止的条件下，等待服务程序运行并重新连接。下面提供了一类异步编程的方法。<br />
网络异步应用涉及到如下几个关键点： <br />
　　客户应用启动后，检测服务应用是否存在。如果不存在，则等待服务应用启动，同时不堵塞客户应用其他任务的执行。一旦服务应用启动，客户应用应该及时的与其建立连接。 <br />
　　客户应用和服务应用在数据通信中，服务应用异常退出后，客户应用应可以检测到服务应用的退出。同时客户应用自动清除该通信链路，回到初始状态，等待服务应用重新启动。<br />
　　该网络异步编程首先涉及到一个定时器和定时器事件。该定时器用于不断的检测网络中客户应用和服务应用是否连通，同时在服务应用出现异常时中止数据通信，返回到初始状态。网络的故障可以通过网络方法的异常处理获知。<br />
　　定时器包含在网络通信类中，使得使用该类的应用感知不到定时器的存在，而方便的处理网络信息。<br />
该客户程序类如下结构： <br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_0_238_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_238_Open_Text.style.display='none'; Codehighlighter1_0_238_Closed_Image.style.display='inline'; Codehighlighter1_0_238_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_0_238_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_0_238_Closed_Text.style.display='none'; Codehighlighter1_0_238_Open_Image.style.display='inline'; Codehighlighter1_0_238_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /><span id="Codehighlighter1_0_238_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_0_238_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;Classname&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;NetComm.java<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;Create&nbsp;Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;5:04:00&nbsp;PM<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;Author&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;Administrator<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;Product&nbsp;Name&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;tagApp<br />
<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;jdom;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.awt.event.ActionEvent;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.awt.event.ActionListener;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.io.BufferedReader;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.io.BufferedWriter;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.io.IOException;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.io.InputStreamReader;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.io.OutputStream;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.io.OutputStreamWriter;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.net.InetAddress;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.net.Socket;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_618_1974_Open_Image" onclick="this.style.display='none'; Codehighlighter1_618_1974_Open_Text.style.display='none'; Codehighlighter1_618_1974_Closed_Image.style.display='inline'; Codehighlighter1_618_1974_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_618_1974_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_618_1974_Closed_Text.style.display='none'; Codehighlighter1_618_1974_Open_Image.style.display='inline'; Codehighlighter1_618_1974_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;NetComm&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;ActionListener&nbsp;</span><span id="Codehighlighter1_618_1974_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_618_1974_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;javax.swing.Timer&nbsp;timer&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;javax.swing.Timer(</span><span style="color: #000000">3000</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;Socket&nbsp;sock;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;EventNotifier&nbsp;en;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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">int</span><span style="color: #000000">&nbsp;net_state&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;InetAddress&nbsp;ServerAddr;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ServerPort;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_850_895_Open_Image" onclick="this.style.display='none'; Codehighlighter1_850_895_Open_Text.style.display='none'; Codehighlighter1_850_895_Closed_Image.style.display='inline'; Codehighlighter1_850_895_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_850_895_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_850_895_Closed_Text.style.display='none'; Codehighlighter1_850_895_Open_Image.style.display='inline'; Codehighlighter1_850_895_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;NetComm(InetAddress&nbsp;addr,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;port)&nbsp;</span><span id="Codehighlighter1_850_895_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_850_895_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServerAddr&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;addr;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServerPort&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;port;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">初始化并创建socket连接</span><span style="color: #008000"><br />
<img id="Codehighlighter1_944_1086_Open_Image" onclick="this.style.display='none'; Codehighlighter1_944_1086_Open_Text.style.display='none'; Codehighlighter1_944_1086_Closed_Image.style.display='inline'; Codehighlighter1_944_1086_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_944_1086_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_944_1086_Closed_Text.style.display='none'; Codehighlighter1_944_1086_Open_Image.style.display='inline'; Codehighlighter1_944_1086_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" /></span><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">void</span><span style="color: #000000">&nbsp;NetComm_Init()&nbsp;</span><span id="Codehighlighter1_944_1086_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_944_1086_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net_state&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />
<img id="Codehighlighter1_970_1020_Open_Image" onclick="this.style.display='none'; Codehighlighter1_970_1020_Open_Text.style.display='none'; Codehighlighter1_970_1020_Closed_Image.style.display='inline'; Codehighlighter1_970_1020_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_970_1020_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_970_1020_Closed_Text.style.display='none'; Codehighlighter1_970_1020_Open_Image.style.display='inline'; Codehighlighter1_970_1020_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_970_1020_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_970_1020_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sock&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Socket(ServerAddr,&nbsp;ServerPort);<br />
<img id="Codehighlighter1_1044_1066_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1044_1066_Open_Text.style.display='none'; Codehighlighter1_1044_1066_Closed_Image.style.display='inline'; Codehighlighter1_1044_1066_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1044_1066_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1044_1066_Closed_Text.style.display='none'; Codehighlighter1_1044_1066_Open_Image.style.display='inline'; Codehighlighter1_1044_1066_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(IOException&nbsp;e)&nbsp;</span><span id="Codehighlighter1_1044_1066_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1044_1066_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net_state&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timer.start();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">创建socket连接</span><span style="color: #008000"><br />
<img id="Codehighlighter1_1135_1729_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1135_1729_Open_Text.style.display='none'; Codehighlighter1_1135_1729_Closed_Image.style.display='inline'; Codehighlighter1_1135_1729_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1135_1729_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1135_1729_Closed_Text.style.display='none'; Codehighlighter1_1135_1729_Open_Image.style.display='inline'; Codehighlighter1_1135_1729_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" /></span><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">void</span><span style="color: #000000">&nbsp;NetComm_Data()&nbsp;</span><span id="Codehighlighter1_1135_1729_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1135_1729_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_1144_1643_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1144_1643_Open_Text.style.display='none'; Codehighlighter1_1144_1643_Closed_Image.style.display='inline'; Codehighlighter1_1144_1643_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1144_1643_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1144_1643_Closed_Text.style.display='none'; Codehighlighter1_1144_1643_Open_Image.style.display='inline'; Codehighlighter1_1144_1643_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_1144_1643_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1144_1643_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputStream&nbsp;outputstream&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;sock.getOutputStream();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BufferedWriter&nbsp;out&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;BufferedWriter(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;OutputStreamWriter(<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;outputstream));<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.write(</span><span style="color: #000000">"</span><span style="color: #000000">java&nbsp;by&nbsp;ghf@china.com</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.flush();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BufferedReader&nbsp;in&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;BufferedReader(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;InputStreamReader(sock<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getInputStream()));<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">boolean</span><span style="color: #000000">&nbsp;more&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">true</span><span style="color: #000000">;<br />
<img id="Codehighlighter1_1482_1623_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1482_1623_Open_Text.style.display='none'; Codehighlighter1_1482_1623_Closed_Image.style.display='inline'; Codehighlighter1_1482_1623_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1482_1623_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1482_1623_Closed_Text.style.display='none'; Codehighlighter1_1482_1623_Open_Image.style.display='inline'; Codehighlighter1_1482_1623_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(more)&nbsp;</span><span id="Codehighlighter1_1482_1623_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1482_1623_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;str&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;in.readLine();<br />
<img id="Codehighlighter1_1537_1562_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1537_1562_Open_Text.style.display='none'; Codehighlighter1_1537_1562_Closed_Image.style.display='inline'; Codehighlighter1_1537_1562_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1537_1562_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1537_1562_Closed_Text.style.display='none'; Codehighlighter1_1537_1562_Open_Image.style.display='inline'; Codehighlighter1_1537_1562_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(str&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)&nbsp;</span><span id="Codehighlighter1_1537_1562_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1537_1562_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;more&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br />
<img id="Codehighlighter1_1569_1618_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1569_1618_Open_Text.style.display='none'; Codehighlighter1_1569_1618_Closed_Image.style.display='inline'; Codehighlighter1_1569_1618_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1569_1618_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1569_1618_Closed_Text.style.display='none'; Codehighlighter1_1569_1618_Open_Image.style.display='inline'; Codehighlighter1_1569_1618_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_1569_1618_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1569_1618_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;处理数据</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(str);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in.close();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_1667_1709_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1667_1709_Open_Text.style.display='none'; Codehighlighter1_1667_1709_Closed_Image.style.display='inline'; Codehighlighter1_1667_1709_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1667_1709_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1667_1709_Closed_Text.style.display='none'; Codehighlighter1_1667_1709_Open_Image.style.display='inline'; Codehighlighter1_1667_1709_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(IOException&nbsp;e)&nbsp;</span><span id="Codehighlighter1_1667_1709_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1667_1709_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NetComm_Close();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net_state&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timer.start();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_1761_1845_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1761_1845_Open_Text.style.display='none'; Codehighlighter1_1761_1845_Closed_Image.style.display='inline'; Codehighlighter1_1761_1845_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1761_1845_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1761_1845_Closed_Text.style.display='none'; Codehighlighter1_1761_1845_Open_Image.style.display='inline'; Codehighlighter1_1761_1845_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;NetComm_Close()&nbsp;</span><span id="Codehighlighter1_1761_1845_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1761_1845_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(sock&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br />
<img id="Codehighlighter1_1790_1813_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1790_1813_Open_Text.style.display='none'; Codehighlighter1_1790_1813_Closed_Image.style.display='inline'; Codehighlighter1_1790_1813_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1790_1813_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1790_1813_Closed_Text.style.display='none'; Codehighlighter1_1790_1813_Open_Image.style.display='inline'; Codehighlighter1_1790_1813_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_1790_1813_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1790_1813_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sock.close();<br />
<img id="Codehighlighter1_1837_1842_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1837_1842_Open_Text.style.display='none'; Codehighlighter1_1837_1842_Closed_Image.style.display='inline'; Codehighlighter1_1837_1842_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1837_1842_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1837_1842_Closed_Text.style.display='none'; Codehighlighter1_1837_1842_Open_Image.style.display='inline'; Codehighlighter1_1837_1842_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(IOException&nbsp;e)&nbsp;</span><span id="Codehighlighter1_1837_1842_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1837_1842_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_1892_1972_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1892_1972_Open_Text.style.display='none'; Codehighlighter1_1892_1972_Closed_Image.style.display='inline'; Codehighlighter1_1892_1972_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1892_1972_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1892_1972_Closed_Text.style.display='none'; Codehighlighter1_1892_1972_Open_Image.style.display='inline'; Codehighlighter1_1892_1972_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;actionPerformed(ActionEvent&nbsp;e)&nbsp;</span><span id="Codehighlighter1_1892_1972_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1892_1972_Open_Text"><span style="color: #000000">{<br />
<img id="Codehighlighter1_1916_1939_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1916_1939_Open_Text.style.display='none'; Codehighlighter1_1916_1939_Closed_Image.style.display='inline'; Codehighlighter1_1916_1939_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1916_1939_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1916_1939_Closed_Text.style.display='none'; Codehighlighter1_1916_1939_Open_Image.style.display='inline'; Codehighlighter1_1916_1939_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(net_state&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;</span><span id="Codehighlighter1_1916_1939_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1916_1939_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NetComm_Init();<br />
<img id="Codehighlighter1_1946_1969_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1946_1969_Open_Text.style.display='none'; Codehighlighter1_1946_1969_Closed_Image.style.display='inline'; Codehighlighter1_1946_1969_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_1946_1969_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_1946_1969_Closed_Text.style.display='none'; Codehighlighter1_1946_1969_Open_Image.style.display='inline'; Codehighlighter1_1946_1969_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_1946_1969_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_1946_1969_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NetComm_Data();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<br />
<p>在以上程序中，也可以为外部应用提供一个回调函数，以便在网络异常或恢复正常时通知应用。服务应用的网络通信类类似，可以放在同一类中。</p>
<img src ="http://www.blogjava.net/jelver/aggbug/189060.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2008-03-27 16:58 <a href="http://www.blogjava.net/jelver/articles/189060.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实战体会Java的多线程编程  【转】</title><link>http://www.blogjava.net/jelver/articles/188126.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Mon, 24 Mar 2008 01:05:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/188126.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/188126.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/188126.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/188126.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/188126.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;在Java 程序中使用多线程要比在 C 或 C++ 中容易得多，这是因为 Java 编程语言提供了语言级的支持。本文通过简单的编程示例来说明 Java 程序中的多线程是多么直观。读完本文以后，用户应该能够编写简单的多线程程序。 　　为什么会排队等待？　　下面的这个简单的 Java 程序完成四项不相关的任务。这样的程序有单个控制线程，控制在这四个任务之间线性地移动。此外，...&nbsp;&nbsp;<a href='http://www.blogjava.net/jelver/articles/188126.html'>阅读全文</a><img src ="http://www.blogjava.net/jelver/aggbug/188126.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2008-03-24 09:05 <a href="http://www.blogjava.net/jelver/articles/188126.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分层模式中的常见问题(zhuan)</title><link>http://www.blogjava.net/jelver/articles/186735.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Mon, 17 Mar 2008 05:14:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/186735.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/186735.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/186735.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/186735.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/186735.html</trackback:ping><description><![CDATA[<h1 style="margin: 17pt 0cm 16.5pt"><span style="font-family: 宋体">引言</span></h1>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体"><font size="3">分层结构是目前复杂应用系统开发时普遍使用的模式，软件中层之间的依赖关系约束是比较宽松的，并不要求上层仅可以依赖于直接下层，而是上层可以依赖于它的所有下层。</font></span></p>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体"><font size="3">设计中我们会把各种系统的各种组件映射至不同层中，而在我所接触的一些实际项目中设计人员在映射这种组件和层间的关系时经常无意中破坏了层结构的依赖关系约束。</font></span></p>
<p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><font size="2"><span style="font-family: 黑体"><img height="456" alt="" src="http://www.java3z.com/cwbwebhome/article/article2/img6/1.jpg" width="187" /></span></font></p>
<p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><font size="2"><span style="font-family: 黑体">图表</span> 1<span style="font-family: 黑体">典型分层结构</span></font></p>
<h1 style="margin: 17pt 0cm 16.5pt"><span style="font-family: 宋体">设计中的常见问题</span></h1>
<h2 style="margin: 13pt 0cm"><span style="font-family: 黑体">问题一</span>:<span style="font-family: 黑体">数据传输对象（</span>DTO<span style="font-family: 黑体">）是否应该属于业务层？</span></h2>
<p style="margin: 0cm 0cm 0pt"><font size="3"><span style="font-family: 宋体">在</span><font face="Times New Roman">J2EE</font><span style="font-family: 宋体">开发的经典著作《</span><font face="Times New Roman">Core J2EE Patterns</font><span style="font-family: 宋体">》中数据传输对象被划分在业务层模式中，那么是否数据传输对象应该被映射到业务层呢？</span></font></p>
<p style="margin: 0cm 0cm 0pt"><font size="3"><span style="font-family: 宋体">数据访问对象（</span><font face="Times New Roman">DAO</font><span style="font-family: 宋体">）在该著作中是被映射到整合层的，这样就会出现一个违反层依赖约束的问题，因为数据访问对象是要依赖于数据传输对象的，因此下层就会出现对上层的依赖了。</span></font></p>
<p style="margin: 0cm 0cm 0pt"><font size="3"><span style="font-family: 宋体">所以本人认为</span><font face="Times New Roman">DTO</font><span style="font-family: 宋体">是在各层中传输数据的，我们可以不必强求的把他们映射到上述层次中，可以把他们放置在一个公共包中。</span></font></p>
<h2 style="margin: 13pt 0cm"><span style="font-family: 黑体">问题二</span>:<span style="font-family: 黑体">使用</span>POJO<span style="font-family: 黑体">作业务对象的轻量级架构与上述层模型的映射</span></h2>
<p style="margin: 0cm 0cm 0pt"><font size="3"><span style="font-family: 宋体">在使用</span><font face="Times New Roman">POJO</font><span style="font-family: 宋体">的轻量级结构中我们通常会使用持久化框架（如</span><font face="Times New Roman">Hibernate/JPA</font><span style="font-family: 宋体">）同时会在架构中引入仓库对象</span><font face="Times New Roman">(Repository Object)</font><span style="font-family: 宋体">，负责业务对象的获取和保存。（注意：他的功能和</span><font face="Times New Roman">DAO</font><span style="font-family: 宋体">是有区别的，仓库对象中通常只应包括业务对象的获取和保存逻辑）。</span></font></p>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体"><font size="3">通常设计人员会把业务对象映射至业务层，而将仓库对象映射至整合层。由于仓库对象对于业务对象的依赖关系就会破坏依赖关系约束，所以这种映射方式显然不正确。</font></span></p>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体"><font size="3">下图是作者推荐的映射方式</font></span></p>
<p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><font size="2"><span style="font-family: 黑体"><img height="761" alt="" src="http://www.java3z.com/cwbwebhome/article/article2/img6/2.jpg" width="470" /></span></font></p>
<p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><font size="2"><span style="font-family: 黑体">图表</span> 2<span style="font-family: 黑体">轻量级架构参考模型</span></font></p>
<p style="margin: 0cm 0cm 0pt"><span style="font-family: 宋体"><font size="3">可以看到业务对象和仓库对象都被映射至业务层，而持久化框架被映射到了整合层。</font></span></p>
<h1 style="margin: 17pt 0cm 16.5pt"><span style="font-family: 宋体">总结</span></h1>
<p><span style="font-size: 10.5pt; font-family: 宋体">因此大家在设计过程中不要仅仅将分层结构留于形式，而要时刻注意设计是否符合这种架构模式，这样才能真正发挥这种架构模式的优势。</span>&nbsp;</p>
<img src ="http://www.blogjava.net/jelver/aggbug/186735.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2008-03-17 13:14 <a href="http://www.blogjava.net/jelver/articles/186735.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>线程同步 (转)</title><link>http://www.blogjava.net/jelver/articles/186530.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Sat, 15 Mar 2008 12:17:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/186530.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/186530.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/186530.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/186530.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/186530.html</trackback:ping><description><![CDATA[<div id="related_topics" style="position: relative" _madepositioned="true" _eventid="2">原文:http://www.javaeye.com/topic/164905<br />
<br />
我们可以在计算机上运行各种计算机软件程序。每一个运行的程序可能包括多个独立运行的线程（Thread）。 <br />
线程（Thread）是一份独立运行的程序，有自己专用的运行栈。线程有可能和其他线程共享一些资源，比如，内存，文件，数据库等。 <br />
当多个线程同时读写同一份共享资源的时候，可能会引起冲突。这时候，我们需要引入线程&#8220;同步&#8221;机制，即各位线程之间要有个先来后到，不能一窝蜂挤上去抢作一团。 <br />
同步这个词是从英文synchronize（使同时发生）翻译过来的。我也不明白为什么要用这个很容易引起误解的词。既然大家都这么用，咱们也就只好这么将就。 <br />
线程同步的真实意思和字面意思恰好相反。线程同步的真实意思，其实是&#8220;排队&#8221;：几个线程之间要排队，一个一个对共享资源进行操作，而不是同时进行操作。 <br />
<br />
因此，关于线程同步，需要牢牢记住的第一点是：线程同步就是线程排队。同步就是排队。线程同步的目的就是避免线程&#8220;同步&#8221;执行。这可真是个无聊的绕口令。 <br />
关于线程同步，需要牢牢记住的第二点是 &#8220;共享&#8221;这两个字。只有共享资源的读写访问才需要同步。如果不是共享资源，那么就根本没有同步的必要。 <br />
关于线程同步，需要牢牢记住的第三点是，只有&#8220;变量&#8221;才需要同步访问。如果共享的资源是固定不变的，那么就相当于&#8220;常量&#8221;，线程同时读取常量也不需要同步。至少一个线程修改共享资源，这样的情况下，线程之间就需要同步。 <br />
关于线程同步，需要牢牢记住的第四点是：多个线程访问共享资源的代码有可能是同一份代码，也有可能是不同的代码；无论是否执行同一份代码，只要这些线程的代码访问同一份可变的共享资源，这些线程之间就需要同步。 <br />
<br />
为了加深理解，下面举几个例子。 <br />
有两个采购员，他们的工作内容是相同的，都是遵循如下的步骤： <br />
（1）到市场上去，寻找并购买有潜力的样品。 <br />
（2）回到公司，写报告。 <br />
这两个人的工作内容虽然一样，他们都需要购买样品，他们可能买到同样种类的样品，但是他们绝对不会购买到同一件样品，他们之间没有任何共享资源。所以，他们可以各自进行自己的工作，互不干扰。 <br />
这两个采购员就相当于两个线程；两个采购员遵循相同的工作步骤，相当于这两个线程执行同一段代码。 <br />
<br />
下面给这两个采购员增加一个工作步骤。采购员需要根据公司的&#8220;布告栏&#8221;上面公布的信息，安排自己的工作计划。 <br />
这两个采购员有可能同时走到布告栏的前面，同时观看布告栏上的信息。这一点问题都没有。因为布告栏是只读的，这两个采购员谁都不会去修改布告栏上写的信息。 <br />
<br />
下面增加一个角色。一个办公室行政人员这个时候，也走到了布告栏前面，准备修改布告栏上的信息。 <br />
如果行政人员先到达布告栏，并且正在修改布告栏的内容。两个采购员这个时候，恰好也到了。这两个采购员就必须等待行政人员完成修改之后，才能观看修改后的信息。 <br />
如果行政人员到达的时候，两个采购员已经在观看布告栏了。那么行政人员需要等待两个采购员把当前信息记录下来之后，才能够写上新的信息。 <br />
上述这两种情况，行政人员和采购员对布告栏的访问就需要进行同步。因为其中一个线程（行政人员）修改了共享资源（布告栏）。而且我们可以看到，行政人员的工作流程和采购员的工作流程（执行代码）完全不同，但是由于他们访问了同一份可变共享资源（布告栏），所以他们之间需要同步。 <br />
<br />
同步锁 <br />
<br />
前面讲了为什么要线程同步，下面我们就来看如何才能线程同步。 <br />
线程同步的基本实现思路还是比较容易理解的。我们可以给共享资源加一把锁，这把锁只有一把钥匙。哪个线程获取了这把钥匙，才有权利访问该共享资源。 <br />
生活中，我们也可能会遇到这样的例子。一些超市的外面提供了一些自动储物箱。每个储物箱都有一把锁，一把钥匙。人们可以使用那些带有钥匙的储物箱，把东西放到储物箱里面，把储物箱锁上，然后把钥匙拿走。这样，该储物箱就被锁住了，其他人不能再访问这个储物箱。（当然，真实的储物箱钥匙是可以被人拿走复制的，所以不要把贵重物品放在超市的储物箱里面。于是很多超市都采用了电子密码锁。） <br />
线程同步锁这个模型看起来很直观。但是，还有一个严峻的问题没有解决，这个同步锁应该加在哪里？ <br />
当然是加在共享资源上了。反应快的读者一定会抢先回答。 <br />
没错，如果可能，我们当然尽量把同步锁加在共享资源上。一些比较完善的共享资源，比如，文件系统，数据库系统等，自身都提供了比较完善的同步锁机制。我们不用另外给这些资源加锁，这些资源自己就有锁。 <br />
但是，大部分情况下，我们在代码中访问的共享资源都是比较简单的共享对象。这些对象里面没有地方让我们加锁。 <br />
读者可能会提出建议：为什么不在每一个对象内部都增加一个新的区域，专门用来加锁呢？这种设计理论上当然也是可行的。问题在于，线程同步的情况并不是很普遍。如果因为这小概率事件，在所有对象内部都开辟一块锁空间，将会带来极大的空间浪费。得不偿失。 <br />
于是，现代的编程语言的设计思路都是把同步锁加在代码段上。确切的说，是把同步锁加在&#8220;访问共享资源的代码段&#8221;上。这一点一定要记住，同步锁是加在代码段上的。 <br />
同步锁加在代码段上，就很好地解决了上述的空间浪费问题。但是却增加了模型的复杂度，也增加了我们的理解难度。 <br />
现在我们就来仔细分析&#8220;同步锁加在代码段上&#8221;的线程同步模型。 <br />
首先，我们已经解决了同步锁加在哪里的问题。我们已经确定，同步锁不是加在共享资源上，而是加在访问共享资源的代码段上。 <br />
其次，我们要解决的问题是，我们应该在代码段上加什么样的锁。这个问题是重点中的重点。这是我们尤其要注意的问题：访问同一份共享资源的不同代码段，应该加上同一个同步锁；如果加的是不同的同步锁，那么根本就起不到同步的作用，没有任何意义。 <br />
这就是说，同步锁本身也一定是多个线程之间的共享对象。 <br />
<br />
Java语言的synchronized关键字 <br />
<br />
为了加深理解，举几个代码段同步的例子。 <br />
不同语言的同步锁模型都是一样的。只是表达方式有些不同。这里我们以当前最流行的Java语言为例。Java语言里面用synchronized关键字给代码段加锁。整个语法形式表现为 <br />
synchronized(同步锁) { <br />
// 访问共享资源，需要同步的代码段 <br />
} <br />
<br />
这里尤其要注意的就是，同步锁本身一定要是共享的对象。 <br />
<br />
&#8230; f1() { <br />
<br />
Object lock1 = new Object(); // 产生一个同步锁 <br />
<br />
synchronized(lock1){ <br />
// 代码段 A <br />
// 访问共享资源 resource1 <br />
// 需要同步 <br />
} <br />
} <br />
<br />
上面这段代码没有任何意义。因为那个同步锁是在函数体内部产生的。每个线程调用这段代码的时候，都会产生一个新的同步锁。那么多个线程之间，使用的是不同的同步锁。根本达不到同步的目的。 <br />
同步代码一定要写成如下的形式，才有意义。 <br />
<br />
public static final Object lock1 = new Object(); <br />
<br />
&#8230; f1() { <br />
<br />
synchronized(lock1){ // lock1 是公用同步锁 <br />
// 代码段 A <br />
// 访问共享资源 resource1 <br />
// 需要同步 <br />
} <br />
<br />
你不一定要把同步锁声明为static或者public，但是你一定要保证相关的同步代码之间，一定要使用同一个同步锁。 <br />
讲到这里，你一定会好奇，这个同步锁到底是个什么东西。为什么随便声明一个Object对象，就可以作为同步锁？ <br />
在Java里面，同步锁的概念就是这样的。任何一个Object Reference都可以作为同步锁。我们可以把Object Reference理解为对象在内存分配系统中的内存地址。因此，要保证同步代码段之间使用的是同一个同步锁，我们就要保证这些同步代码段的synchronized关键字使用的是同一个Object Reference，同一个内存地址。这也是为什么我在前面的代码中声明lock1的时候，使用了final关键字，这就是为了保证lock1的Object Reference在整个系统运行过程中都保持不变。 <br />
一些求知欲强的读者可能想要继续深入了解synchronzied(同步锁)的实际运行机制。Java虚拟机规范中（你可以在google用&#8220;JVM Spec&#8221;等关键字进行搜索），有对synchronized关键字的详细解释。synchronized会编译成 monitor enter, &#8230; monitor exit之类的指令对。Monitor就是实际上的同步锁。每一个Object Reference在概念上都对应一个monitor。 <br />
这些实现细节问题，并不是理解同步锁模型的关键。我们继续看几个例子，加深对同步锁模型的理解。 <br />
<br />
public static final Object lock1 = new Object(); <br />
<br />
&#8230; f1() { <br />
<br />
synchronized(lock1){ // lock1 是公用同步锁 <br />
// 代码段 A <br />
// 访问共享资源 resource1 <br />
// 需要同步 <br />
} <br />
} <br />
<br />
&#8230; f2() { <br />
<br />
synchronized(lock1){ // lock1 是公用同步锁 <br />
// 代码段 B <br />
// 访问共享资源 resource1 <br />
// 需要同步 <br />
} <br />
} <br />
<br />
上述的代码中，代码段A和代码段B就是同步的。因为它们使用的是同一个同步锁lock1。 <br />
如果有10个线程同时执行代码段A，同时还有20个线程同时执行代码段B，那么这30个线程之间都是要进行同步的。 <br />
这30个线程都要竞争一个同步锁lock1。同一时刻，只有一个线程能够获得lock1的所有权，只有一个线程可以执行代码段A或者代码段B。其他竞争失败的线程只能暂停运行，进入到该同步锁的就绪（Ready）队列。 <br />
每一个同步锁下面都挂了几个线程队列，包括就绪（Ready）队列，待召（Waiting）队列等。比如，lock1对应的就绪队列就可以叫做lock1 - ready queue。每个队列里面都可能有多个暂停运行的线程。 <br />
注意，竞争同步锁失败的线程进入的是该同步锁的就绪（Ready）队列，而不是后面要讲述的待召队列（Waiting Queue，也可以翻译为等待队列）。就绪队列里面的线程总是时刻准备着竞争同步锁，时刻准备着运行。而待召队列里面的线程则只能一直等待，直到等到某个信号的通知之后，才能够转移到就绪队列中，准备运行。 <br />
成功获取同步锁的线程，执行完同步代码段之后，会释放同步锁。该同步锁的就绪队列中的其他线程就继续下一轮同步锁的竞争。成功者就可以继续运行，失败者还是要乖乖地待在就绪队列中。 <br />
因此，线程同步是非常耗费资源的一种操作。我们要尽量控制线程同步的代码段范围。同步的代码段范围越小越好。我们用一个名词&#8220;同步粒度&#8221;来表示同步代码段的范围。 <br />
同步粒度 <br />
在Java语言里面，我们可以直接把synchronized关键字直接加在函数的定义上。 <br />
比如。 <br />
&#8230; synchronized &#8230; f1() { <br />
// f1 代码段 <br />
} <br />
<br />
这段代码就等价于 <br />
&#8230; f1() { <br />
synchronized(this){ // 同步锁就是对象本身 <br />
// f1 代码段 <br />
} <br />
} <br />
<br />
同样的原则适用于静态（static）函数 <br />
比如。 <br />
&#8230; static synchronized &#8230; f1() { <br />
// f1 代码段 <br />
} <br />
<br />
这段代码就等价于 <br />
&#8230;static &#8230; f1() { <br />
synchronized(Class.forName(&#8230;)){ // 同步锁是类定义本身 <br />
// f1 代码段 <br />
} <br />
} <br />
<br />
但是，我们要尽量避免这种直接把synchronized加在函数定义上的偷懒做法。因为我们要控制同步粒度。同步的代码段越小越好。synchronized控制的范围越小越好。 <br />
我们不仅要在缩小同步代码段的长度上下功夫，我们同时还要注意细分同步锁。 <br />
比如，下面的代码 <br />
<br />
public static final Object lock1 = new Object(); <br />
<br />
&#8230; f1() { <br />
<br />
synchronized(lock1){ // lock1 是公用同步锁 <br />
// 代码段 A <br />
// 访问共享资源 resource1 <br />
// 需要同步 <br />
} <br />
} <br />
<br />
&#8230; f2() { <br />
<br />
synchronized(lock1){ // lock1 是公用同步锁 <br />
// 代码段 B <br />
// 访问共享资源 resource1 <br />
// 需要同步 <br />
} <br />
} <br />
<br />
&#8230; f3() { <br />
<br />
synchronized(lock1){ // lock1 是公用同步锁 <br />
// 代码段 C <br />
// 访问共享资源 resource2 <br />
// 需要同步 <br />
} <br />
} <br />
<br />
&#8230; f4() { <br />
<br />
synchronized(lock1){ // lock1 是公用同步锁 <br />
// 代码段 D <br />
// 访问共享资源 resource2 <br />
// 需要同步 <br />
} <br />
} <br />
<br />
上述的4段同步代码，使用同一个同步锁lock1。所有调用4段代码中任何一段代码的线程，都需要竞争同一个同步锁lock1。 <br />
我们仔细分析一下，发现这是没有必要的。 <br />
因为f1()的代码段A和f2()的代码段B访问的共享资源是resource1，f3()的代码段C和f4()的代码段D访问的共享资源是resource2，它们没有必要都竞争同一个同步锁lock1。我们可以增加一个同步锁lock2。f3()和f4()的代码可以修改为： <br />
public static final Object lock2 = new Object(); <br />
<br />
&#8230; f3() { <br />
<br />
synchronized(lock2){ // lock2 是公用同步锁 <br />
// 代码段 C <br />
// 访问共享资源 resource2 <br />
// 需要同步 <br />
} <br />
} <br />
<br />
&#8230; f4() { <br />
<br />
synchronized(lock2){ // lock2 是公用同步锁 <br />
// 代码段 D <br />
// 访问共享资源 resource2 <br />
// 需要同步 <br />
} <br />
} <br />
<br />
这样，f1()和f2()就会竞争lock1，而f3()和f4()就会竞争lock2。这样，分开来分别竞争两个锁，就可以大大较少同步锁竞争的概率，从而减少系统的开销。 <br />
<br />
信号量 <br />
<br />
同步锁模型只是最简单的同步模型。同一时刻，只有一个线程能够运行同步代码。 <br />
有的时候，我们希望处理更加复杂的同步模型，比如生产者/消费者模型、读写同步模型等。这种情况下，同步锁模型就不够用了。我们需要一个新的模型。这就是我们要讲述的信号量模型。 <br />
信号量模型的工作方式如下：线程在运行的过程中，可以主动停下来，等待某个信号量的通知；这时候，该线程就进入到该信号量的待召（Waiting）队列当中；等到通知之后，再继续运行。 <br />
很多语言里面，同步锁都由专门的对象表示，对象名通常叫Monitor。 <br />
同样，在很多语言中，信号量通常也有专门的对象名来表示，比如，Mutex，Semphore。 <br />
信号量模型要比同步锁模型复杂许多。一些系统中，信号量甚至可以跨进程进行同步。另外一些信号量甚至还有计数功能，能够控制同时运行的线程数。 <br />
我们没有必要考虑那么复杂的模型。所有那些复杂的模型，都是最基本的模型衍生出来的。只要掌握了最基本的信号量模型——&#8220;等待/通知&#8221;模型，复杂模型也就迎刃而解了。 <br />
我们还是以Java语言为例。Java语言里面的同步锁和信号量概念都非常模糊，没有专门的对象名词来表示同步锁和信号量，只有两个同步锁相关的关键字——volatile和synchronized。 <br />
这种模糊虽然导致概念不清，但同时也避免了Monitor、Mutex、Semphore等名词带来的种种误解。我们不必执着于名词之争，可以专注于理解实际的运行原理。 <br />
在Java语言里面，任何一个Object Reference都可以作为同步锁。同样的道理，任何一个Object Reference也可以作为信号量。 <br />
Object对象的wait()方法就是等待通知，Object对象的notify()方法就是发出通知。 <br />
具体调用方法为 <br />
（1）等待某个信号量的通知 <br />
public static final Object signal = new Object(); <br />
<br />
&#8230; f1() { <br />
synchronized(singal) { // 首先我们要获取这个信号量。这个信号量同时也是一个同步锁 <br />
<br />
// 只有成功获取了signal这个信号量兼同步锁之后，我们才可能进入这段代码 <br />
signal.wait(); // 这里要放弃信号量。本线程要进入signal信号量的待召（Waiting）队列 <br />
<br />
// 可怜。辛辛苦苦争取到手的信号量，就这么被放弃了 <br />
<br />
// 等到通知之后，从待召（Waiting）队列转到就绪（Ready）队列里面 <br />
// 转到了就绪队列中，离CPU核心近了一步，就有机会继续执行下面的代码了。 <br />
// 仍然需要把signal同步锁竞争到手，才能够真正继续执行下面的代码。命苦啊。 <br />
&#8230; <br />
} <br />
} <br />
<br />
需要注意的是，上述代码中的signal.wait()的意思。signal.wait()很容易导致误解。signal.wait()的意思并不是说，signal开始wait，而是说，运行这段代码的当前线程开始wait这个signal对象，即进入signal对象的待召（Waiting）队列。 <br />
<br />
（2）发出某个信号量的通知 <br />
&#8230; f2() { <br />
synchronized(singal) { // 首先，我们同样要获取这个信号量。同时也是一个同步锁。 <br />
<br />
// 只有成功获取了signal这个信号量兼同步锁之后，我们才可能进入这段代码 <br />
signal.notify(); // 这里，我们通知signal的待召队列中的某个线程。 <br />
<br />
// 如果某个线程等到了这个通知，那个线程就会转到就绪队列中 <br />
// 但是本线程仍然继续拥有signal这个同步锁，本线程仍然继续执行 <br />
// 嘿嘿，虽然本线程好心通知其他线程， <br />
// 但是，本线程可没有那么高风亮节，放弃到手的同步锁 <br />
// 本线程继续执行下面的代码 <br />
&#8230; <br />
} <br />
} <br />
<br />
需要注意的是，signal.notify()的意思。signal.notify()并不是通知signal这个对象本身。而是通知正在等待signal信号量的其他线程。 <br />
<br />
以上就是Object的wait()和notify()的基本用法。 <br />
实际上，wait()还可以定义等待时间，当线程在某信号量的待召队列中，等到足够长的时间，就会等无可等，无需再等，自己就从待召队列转移到就绪队列中了。 <br />
另外，还有一个notifyAll()方法，表示通知待召队列里面的所有线程。 <br />
这些细节问题，并不对大局产生影响。 <br />
<br />
绿色线程 <br />
<br />
绿色线程（Green Thread）是一个相对于操作系统线程（Native Thread）的概念。 <br />
操作系统线程（Native Thread）的意思就是，程序里面的线程会真正映射到操作系统的线程，线程的运行和调度都是由操作系统控制的 <br />
绿色线程（Green Thread）的意思是，程序里面的线程不会真正映射到操作系统的线程，而是由语言运行平台自身来调度。 <br />
当前版本的Python语言的线程就可以映射到操作系统线程。当前版本的Ruby语言的线程就属于绿色线程，无法映射到操作系统的线程，因此Ruby语言的线程的运行速度比较慢。 <br />
难道说，绿色线程要比操作系统线程要慢吗？当然不是这样。事实上，情况可能正好相反。Ruby是一个特殊的例子。线程调度器并不是很成熟。 <br />
目前，线程的流行实现模型就是绿色线程。比如，stackless Python，就引入了更加轻量的绿色线程概念。在线程并发编程方面，无论是运行速度还是并发负载上，都优于Python。 <br />
另一个更著名的例子就是ErLang（爱立信公司开发的一种开源语言）。 <br />
ErLang的绿色线程概念非常彻底。ErLang的线程不叫Thread，而是叫做Process。这很容易和进程混淆起来。这里要注意区分一下。 <br />
ErLang Process之间根本就不需要同步。因为ErLang语言的所有变量都是final的，不允许变量的值发生任何变化。因此根本就不需要同步。 <br />
final变量的另一个好处就是，对象之间不可能出现交叉引用，不可能构成一种环状的关联，对象之间的关联都是单向的，树状的。因此，内存垃圾回收的算法效率也非常高。这就让ErLang能够达到Soft Real Time（软实时）的效果。这对于一门支持内存垃圾回收的语言来说，可不是一件容易的事情。 </div>
<img src ="http://www.blogjava.net/jelver/aggbug/186530.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2008-03-15 20:17 <a href="http://www.blogjava.net/jelver/articles/186530.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常用的多线程异步处理</title><link>http://www.blogjava.net/jelver/articles/184502.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Fri, 07 Mar 2008 06:13:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/184502.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/184502.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/184502.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/184502.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/184502.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: package&nbsp;cn.allinpalm.sns.app.web.point.action;import&nbsp;java.util.LinkedList;import&nbsp;org.apache.log4j.Logger;import&nbsp;cn.allinpalm.sns.app.web.constants.Config;import&nbsp;cn...&nbsp;&nbsp;<a href='http://www.blogjava.net/jelver/articles/184502.html'>阅读全文</a><img src ="http://www.blogjava.net/jelver/aggbug/184502.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2008-03-07 14:13 <a href="http://www.blogjava.net/jelver/articles/184502.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>程序员面试题（转）</title><link>http://www.blogjava.net/jelver/articles/183353.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Mon, 03 Mar 2008 01:02:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/183353.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/183353.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/183353.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/183353.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/183353.html</trackback:ping><description><![CDATA[答题时间20分钟 <br />
1. <br />
System.out.println(1+&#8217;\002&#8217;)会打印出多少? ___8进制______ <br />
System.out.println(1+2+&#8221;3&#8221;)会打印出多少? _________ <br />
<br />
2. 请简单补充完下面jdbc读取数据的实现 <br />
String SQL = &#8220;SELECT id , title, description FROM t_blog WHERE id = ?&#8221;; <br />
long id; <br />
String title; <br />
String description; <br />
Connection conn = null;//假设用ConnectionManager.getConnection();可以获得连接对象 <br />
PrepareStatement pstmt = null; <br />
<br />
<br />
<br />
如果description字段在数据库中是text类型，而且存储的文字比较多（20K左右），这时候该如何优化读取，让系统支撑更大的并发？ <br />
<br />
3. 有一篇文章的URL为 view.jsp?id=100 ，每分钟访问量可能上千次，在记录和显示它的查看次数时，你觉得如何做性能比较好？ <br />
<br />
4. 写出你最常见到的一些运行时异常(runtime exception)，再简述一下你是如何避免java 中空指针异常的 <br />
<br />
5. 你用lucene做过全文检索吗? 简单描述一下你的经验。<br />
<br />
6. 简述一下你对GC的理解，以及如何避免内存泄露。 <br />
<br />
7. 要求最后打印出的全部是数字，下面的程序满足要求吗？还可以再优化吗？请简单描述。 <br />
String strA = &#8220;1:2:3:4:5:6:7:8:9:10:&#8221;; <br />
String arrA[] = strA.split(&#8220;:&#8221;); <br />
for(int i=0;i&lt;arrA.length;i++) <br />
{ <br />
System.out.println(arrA[i]); <br />
} <br />
<br />
8. 简述一下javascript/dhtml/css/ajax在你以前项目中的应用程度；熟悉跨浏览器兼容javascript/css吗? 有兴趣对它们进行深入研究吗？ <br />
<br />
<br />
9. 你最熟悉Web开发过程中的哪部分？&gt; <br />
<img src ="http://www.blogjava.net/jelver/aggbug/183353.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2008-03-03 09:02 <a href="http://www.blogjava.net/jelver/articles/183353.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDK1.5中引入了对java语言的多种扩展</title><link>http://www.blogjava.net/jelver/articles/180749.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Tue, 19 Feb 2008 14:11:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/180749.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/180749.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/180749.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/180749.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/180749.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JDK1.5中引入了对java语言的多种扩展，泛型(generics)即其中之一。这个教程的目标是向您介绍java的泛型(generic)。你可能熟悉其他语言的泛型，最著名的是C++的模板(templates)。如果这样，你很快就会看到两者的相似之处和重要差异。如果你不熟悉相似的语法结构，那么更好，你可以从头开始而不需要忘记误解。Generics允许对类型进行抽象(abstract ove...&nbsp;&nbsp;<a href='http://www.blogjava.net/jelver/articles/180749.html'>阅读全文</a><img src ="http://www.blogjava.net/jelver/aggbug/180749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jelver/" target="_blank">冰河快狼</a> 2008-02-19 22:11 <a href="http://www.blogjava.net/jelver/articles/180749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>泛型是J2SE 5.0最重要的特性</title><link>http://www.blogjava.net/jelver/articles/180746.html</link><dc:creator>冰河快狼</dc:creator><author>冰河快狼</author><pubDate>Tue, 19 Feb 2008 14:08:00 GMT</pubDate><guid>http://www.blogjava.net/jelver/articles/180746.html</guid><wfw:comment>http://www.blogjava.net/jelver/comments/180746.html</wfw:comment><comments>http://www.blogjava.net/jelver/articles/180746.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jelver/comments/commentRss/180746.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jelver/services/trackbacks/180746.html</trackback:ping><description><![CDATA[英文原文地址:<br />
<a href="http://www.onjava.com/pub/a/onjava/2005/07/06/generics.html" target="_new">http://www.onjava.com/pub/a/onjava/2005/07/06/generics.html</a><br />
中文地址:<br />
<a href="http://www.matrix.org.cn/resource/article/43/43634_java_generics.html" target="_new">http://www.matrix.org.cn/resource/article/43/43634_java_generics.html</a><br />
关键词： java generics java5<br />
<br />
<strong>摘要</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 泛型是J2SE 5.0最重要的特性。他们让你写一个type(类或接口）和创建一个实例通过传递一个或多个引用类型。这个实例受限于只能作用于这些类型。比如，在java 5，java.util.List 已经被泛化。当建立一个list对象时，你通过传递一个java类型建立一个List实例，此list实例只能作用于所传递的类型。这意味着如果你传递一个String ,此List实例只能拥有String对象；如果你传递一个Integer，此实例只能存贮Integer对象。除了创建参数化的类型，你还能创建参数化的函数。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 泛型的第一个好处是编译时的严格类型检查。这是集合框架最重要的特点。此外,泛型消除了绝大多数的类型转换。在JDK 5.0之前，当你使用集合框架时，你不得不进行类型转换。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 本文将教你如何操作泛型。它的第一部分是&#8220;没有泛型的日子&#8221;，先让我们回忆老版本JDK的不便。然后，举一些泛型的例子。在讨论完语法以及有界泛型的使用之后，文章最后一章将解释如何写泛型。<br />
&nbsp;&nbsp;<br />
<br />
<strong>没有泛型的日子</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp; 所有的java类都源自java.lang.Object,这意味着所有的JAVA对象能转换成Object。因此，在之前的JDK的版本中，很多集合框架的函数接受一个Object参数。所以，collections是一个能持有任何对象的多用途工具，但带来了不良的后果。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; 举个简单的例子，在JDK 5.0的之前版本中，类List的函数add接受一个Object参数：<br />
<br />
<pre class="overflow" title="pre code">public boolean add(java.lang.Object element)</pre>
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所以你能传递任何类型给add。这是故意这么设计的。否则，它只能传递某种特定的对象，这样就会出现各种List类型，如，StringList, EmployeeList, AddressList等。<br />
&nbsp;&nbsp;&nbsp;&nbsp; add通过Object传递能带来好处,现在我们考虑get函数(返回List中的一个元素).如下是JDK 5之前版本的定义：<br />
<br />
<pre class="overflow" title="pre code">public java.lang.Object get(int index) throws IndexOutOfBoundsException</pre>
<br />
<br />
get返回一个Object.不幸的事情从此开始了.假如你储存了两个String对象在一个List中:<br />
<br />
<pre class="overflow" title="pre code">List stringList1 = new ArrayList();<br />
stringList1.add("Java 5");<br />
stringList1.add("with generics");</pre>
<br />
<br />
当你想从stringList1取得一个元素时,你得到了一个Object.为了操作原来的类型元素,你不得不把它转换为String。<br />
<br />
<pre class="overflow" title="pre code">String s1 = (String) stringList1.get(0);</pre>
<br />
<br />
但是,假如你曾经把一个非String对象加入stringList1中,上面的代码会抛出一个ClassCastException. 有了泛型,你能创建一个单一用途的List实例.比如,你能创建一个只接受String对象的List实例,另外一个实例只能接受Employee对象.这同样适用于集合框架中的其他类型.<br />
<br />
<br />
<strong>泛型入门</strong><br />
<br />
&nbsp;&nbsp; 像一个函数能接受参数一样,一个泛型也能接受参数.这就是一个泛型经常被称为一个参数化类型的原因.但是不像函数用()传递参数,泛型是用&lt;&gt;传递参数的.声明一个泛型和声明一个普通类没有什么区别,只不过你把泛型的变量放在&lt;&gt;中.<br />
&nbsp;&nbsp;&nbsp;&nbsp; 比如,在JDK 5中,你可以这样声明一个java.util.List :&nbsp;&nbsp;List&lt;E&gt; myList;<br />
E 称为类型变量.意味着一个变量将被一个类型替代.替代类型变量的值将被当作参数或返回类型.对于List接口来说,当一个实例被创建以后,E 将被当作一个add或别的函数的参数.E 也会使get或别的参数的返回值.下面是add和get的定义:<br />
<br />
<pre class="overflow" title="pre code">boolean add&lt;E o&gt;<br />
E get(int index)</pre>
<br />
<br />
<span style="color: red">NOTE:</span>一个泛型在声明或例示时允许你传递特定的类型变量: E.除此之外,如果E是个类，你可以传递子类；如果E是个接口，你可以传递实现接口的类；<br />
<br />
<span style="color: purple">-----------------------------译者添加--------------------<br />
List&lt;Number&gt; numberList= new ArrayList&lt;Number&gt;();<br />
&nbsp;&nbsp; numberList.add(2.0);<br />
&nbsp;&nbsp; numberList.add(2);<br />
-----------------------------译者添加--------------------</span><br />
<br />
如果你传递一个String给一个List，比如：<br />
<br />
<pre class="overflow" title="pre code">List&lt;String&gt; myList;</pre>
<br />
<br />
那么mylist的add函数将接受一个String作为他的参数，而get函数将返回一个String.因为返回了一个特定的类型，所以不用类型转化了。<br />
<br />
<span style="color: red">NOTE</span>：根据惯例，我们使用一个唯一的大写字目表示一个类型变量。为了创建一个泛型，你需在声明时传递同样的参数列表。比如，你要想创建一个ArrayList来操作String ，你必须把String放在&lt;&gt;中。如：<br />
<br />
<pre class="overflow" title="pre code">List&lt;String&gt; myList = new ArrayList&lt;String&gt;();</pre>
<br />
<br />
再比如，java.util.Map 是这么定义的：<br />
<br />
<pre class="overflow" title="pre code">public interface Map&lt;K,V&gt;</pre>
<br />
<br />
K用来声明map键(KEY)的类型而V用来表示值(VALUE)的类型。put和values是这么定义的：<br />
<br />
<pre class="overflow" title="pre code">V put(K key, V value)<br />
Collection&lt;V&gt; values()</pre>
<br />
<br />
<span style="color: red">NOTE</span>:一个泛型不准直接的或间接的是java.lang.Throwable的子类。因为异常是在运行时抛出的,所以它不可能预言什么类型的异常将在编译时抛出.<br />
<br />
列表1的例子将比较List在JDK 1.4 和JDK1.5的不同<br />
<br />
<pre class="overflow" title="pre code">package com.brainysoftware.jdk5.app16;<br />
import java.util.List;<br />
import java.util.ArrayList;<br />
<br />
public class GenericListTest {<br />
&nbsp;&nbsp;public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;// in JDK 1.4<br />
&nbsp;&nbsp;&nbsp;&nbsp;List stringList1 = new ArrayList();<br />
&nbsp;&nbsp;&nbsp;&nbsp;stringList1.add("Java 1.0 - 5.0");<br />
&nbsp;&nbsp;&nbsp;&nbsp;stringList1.add("without generics");<br />
&nbsp;&nbsp;&nbsp;&nbsp;// cast to java.lang.String<br />
&nbsp;&nbsp;&nbsp;&nbsp;String s1 = (String) stringList1.get(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(s1.toUpperCase());<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;// now with generics in JDK 5<br />
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;String&gt; stringList2 = new ArrayList&lt;String&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;stringList2.add("Java 5.0");<br />
&nbsp;&nbsp;&nbsp;&nbsp;stringList2.add("with generics");<br />
&nbsp;&nbsp;&nbsp;&nbsp;// no need for type casting<br />
&nbsp;&nbsp;&nbsp;&nbsp;String s2 = stringList2.get(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(s2.toUpperCase());<br />
&nbsp;&nbsp;}<br />
}</pre>
<br />
<br />
在列表1中，stringList2是个泛型。声明List&lt;String&gt;告诉编译器List的实例能接受一个String对象。当然，在另外的情况中，你能新建能接受各种对象的List实例。注意，当从List实例中返回成员元素时，不需要对象转化，因为他返回的了你想要的类型，也就是String.<br />
<br />
<span style="color: red">NOTE</span>:泛型的类型检查(type checking)是在编译时完成的.<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最让人感兴趣的事情是，一个泛型是个类型并且能被当作一个类型变量。比如，你想你的List储存lists of Strings,你能通过把List&lt;String&gt;作为他的类型变量来声明List。比如：<br />
<br />
<pre class="overflow" title="pre code">List&lt;List&lt;String&gt;&gt; myListOfListsOfStrings;</pre>
<br />
<br />
要从myList中的第一个List重新取得String，你可以这么用：<br />
<br />
<pre class="overflow" title="pre code">String s = myListOfListsOfStrings.get(0).get(0);</pre>
<br />
<br />
下一个列表中的ListOfListsTest类示范了一个List（命名为listOfLists）接受一个String List作为参数。<br />
<br />
<pre class="overflow" title="pre code">package com.brainysoftware.jdk5.app16;<br />
import java.util.ArrayList;<br />
import java.util.List;<br />
public class ListOfListsTest {<br />
&nbsp;&nbsp;public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;String&gt; listOfStrings = new ArrayList&lt;String&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;listOfStrings.add("Hello again");<br />
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;List&lt;String&gt;&gt; listOfLists = new ArrayList&lt;List&lt;String&gt;&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;listOfLists.add(listOfStrings);<br />
&nbsp;&nbsp;&nbsp;&nbsp;String s = listOfLists.get(0).get(0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(s); // prints "Hello again"<br />
&nbsp;&nbsp;}<br />
}</pre>
<br />
<br />
另外，一个泛型接受一个或多个类型变量。比如，java.util.Map有两个类型变量s。第一个定义了键（key）的类型，第二个定义了值（value)的类型。下面的例子讲教我们如何使用个一个泛型Map.<br />
<br />
<pre class="overflow" title="pre code">package com.brainysoftware.jdk5.app16;<br />
import java.util.HashMap;<br />
import java.util.Map;<br />
public class MapTest {<br />
&nbsp;&nbsp;public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;Map&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;map.put("key1", "value1");<br />
&nbsp;&nbsp;&nbsp;&nbsp;map.put("key2", "value2");<br />
&nbsp;&nbsp;&nbsp;&nbsp;String value1 = map.get("key1");<br />
&nbsp;&nbsp;}<br />
}</pre>
<br />
<br />
在这个例子中，重新得到一个key1代表的String值，我们不需要任何类型转换。<br />
<br />
<strong>没有参数的情况下使用泛型</strong><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;既然在J2SE 5.0中收集类型已经泛型化，那么，原来的使用这些类型的代码将如何呢？很幸运，他们在JAVA 5中将继续工作，因为你能使用没有参数的泛型。比如，你能继续像原来一样使用List接口，正如下面的例子一样。<br />
<br />
<pre class="overflow" title="pre code">List stringList1 = new ArrayList();<br />
stringList1.add("Java 1.0 - 5.0");<br />
stringList1.add("without generics");<br />
String s1 = (String) stringList1.get(0);</pre>
<br />
<br />
一个没有任何参数的泛型被称为原型(raw type)。它意味着这些为JDK1.4或更早的版本而写的代码将继续在java 5中工作。<br />
<br />
尽管如此，一个需要注意的事情是，JDK５编译器希望你使用带参数的泛型。否则，编译器将提示警告，因为他认为你可能忘了定义类型变量s。比如，编译上面的代码的时候你会看到下面这些警告，因为第一个List被认为是原型。<br />
<br />
Note: com/brainysoftware/jdk5/app16/GenericListTest.java<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uses unchecked or unsafe operations.<br />
Note: Recompile with -Xlint:unchecked for details.<br />
<br />
当你使用原型时，如果你不想看到这些警告，你有几个选择来达到目的：<br />
1.编译时带上参数-source 1.4<br />
2.使用@SupressWarnings("unchecked")注释<br />
3.更新你的代码，使用List&lt;Object&gt;. List&lt;Object&gt;的实例能接受任何类型的对象，就像是一个原型List。然而，编译器不会报错。<br />
<br />
<strong>使用 ？ 通配符</strong><br />
&nbsp;&nbsp; 前面提过，如果你声明了一个List&lt;aType&gt;, 那么这个List对aType起作用，所以你能储存下面这些类型的对象：<br />
1.一个aType的实例<br />
2.它的子类的实例(如果aType是个类)<br />
3.实现aType接口的类实例(如果aType是个接口)<br />
但是，请注意，一个泛型本身是个JAVA类型，就像java.lang.String或java.io.File一样。传递不同的类型变量给泛型可以创建不同的JAVA类型。比如，下面例子中list1和list2引用了不同的类型对象。<br />
<br />
<pre class="overflow" title="pre code">List&lt;Object&gt; list1 = new ArrayList&lt;Object&gt;();<br />
List&lt;String&gt; list2 = new ArrayList&lt;String&gt;();</pre>
<br />
<br />
list1指向了一个类型变量s为java.lang.Objects 的List而list2指向了一个类型变量s为String 的List。所以传递一个List&lt;String&gt;给一个参数为List&lt;Object&gt;的函数将导致compile time错误。下面列表可以说明：<br />
<pre class="overflow" title="pre code">package com.brainysoftware.jdk5.app16;<br />
import java.util.ArrayList;<br />
import java.util.List;<br />
<br />
public class AllowedTypeTest {<br />
&nbsp;&nbsp;public static void doIt(List&lt;Object&gt; l) {<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;String&gt; myList = new ArrayList&lt;String&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;// 这里将产生一个错误<br />
&nbsp;&nbsp;&nbsp;&nbsp;doIt(myList);<br />
&nbsp;&nbsp;}<br />
}</pre>
<br />
上面的代码无法编译，因为你试图传递一个错误的类型给函数doIt。doIt的参数是List&lt;Object&gt;二你传递的参数是List&lt;String&gt;。<br />
可以使用 ？ 通配符解决这个难题。List&lt;?&gt; 意味着一个对任何对象起作用的List。所以，doIt可以改为：<br />
<br />
<pre class="overflow" title="pre code">public static void doIt(List&lt;?&gt; l) {}</pre>
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;在某些情况下你会考虑使用 ? 通配符。比如，你有一个printList函数，这个函数打印一个List的所有成员，你想让这个函数对任何类型的List起作用时。否则，你只能累死累活的写很多printList的重载函数。下面的列表引用了使用 ? 通配符的printList函数。<br />
<pre class="overflow" title="pre code">package com.brainysoftware.jdk5.app16;<br />
import java.util.ArrayList;<br />
import java.util.List;<br />
<br />
public class WildCardTest {<br />
<br />
&nbsp;&nbsp;public static void printList(List&lt;?&gt; list) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;for (Object element : list) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(element);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;String&gt; list1 = new ArrayList&lt;String&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;list1.add("Hello");<br />
&nbsp;&nbsp;&nbsp;&nbsp;list1.add("World");<br />
&nbsp;&nbsp;&nbsp;&nbsp;printList(list1);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Integer&gt; list2 = new ArrayList&lt;Integer&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;list2.add(100);<br />
&nbsp;&nbsp;&nbsp;&nbsp;list2.add(200);<br />
&nbsp;&nbsp;&nbsp;&nbsp;printList(list2);<br />
&nbsp;&nbsp;}<br />
}</pre>
<br />
<br />
这些代码说明了在printList函数中，List&lt;?&gt;表示各种类型的List对象。然而，请注意，在声明的时候使用 ? 通配符是不合法的，像这样：<br />
<br />
<pre class="overflow" title="pre code">List&lt;?&gt; myList = new ArrayList&lt;?&gt;(); // 不合法</pre>
<br />
<br />
如果你想创建一个接收任何类型对象的List，你可以使用Object作为类型变量，就像这样：<br />
<br />
<pre class="overflow" title="pre code">List&lt;Object&gt; myList = new ArrayList&lt;Object&gt;();</pre>
<br />
<br />
<strong>在函数中使用界限通配符</strong><br />
在之前的章节中，你学会了通过传递不同的类型变量s来创建不同JAVA类型的泛型，但并不考虑类型变量s之间的继承关系。在很多情况下，你想一个函数有不同的List参数。比如，你有一个函数getAverage，他返回了一个List中成员的平均值。然而，如果你把List&lt;Number&gt;作为getAverage的参数，你就没法传递List&lt;Integer&gt; 或List&lt;Double&gt;参数，因为List&lt;Number&gt;和List&lt;Integer&gt; 和List&lt;Double&gt;不是同样的类型。<br />
<br />
你能使用原型或使用通配符，但这样无法在编译时进行安全类型检查，因为你能传递任何类型的List，比如List&lt;String&gt;的实例。你可以使用List&lt;Number&gt;作为参数，但是你就只能传递List&lt;Number&gt;给函数。但这样就使你的函数功能减少，因为你可能更多的时候要操作List&lt;Integer&gt;或List&lt;Long&gt;，而不是List&lt;Number&gt;。<br />
<br />
J2SE5.0增加了一个规则来解决了这种约束，这个规则就是允许你定义一个上界(upper bound) 类型变量.在这种方式中，你能传递一个类型或它的子类。在上面getAverage函数的例子中，你能传递一个List&lt;Number&gt;或它的子类的实例，比如List&lt;Integer&gt; or List&lt;Float&gt;。<br />
<br />
使用上界规则的语法这么定义的：GenericType&lt;? extends upperBoundType&gt;. 比如，对getAverage函数的参数，你可以这么写List&lt;? extends Number&gt;. 下面例子说明了如何使用这种规则。<br />
<pre class="overflow" title="pre code">package com.brainysoftware.jdk5.app16;<br />
import java.util.ArrayList;<br />
import java.util.List;<br />
public class BoundedWildcardTest {<br />
&nbsp;&nbsp;public static double getAverage(List&lt;? extends Number&gt; numberList)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;double total = 0.0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;for (Number number : numberList)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;total += number.doubleValue();<br />
&nbsp;&nbsp;&nbsp;&nbsp;return total/numberList.size();<br />
&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Integer&gt; integerList = new ArrayList&lt;Integer&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;integerList.add(3);<br />
&nbsp;&nbsp;&nbsp;&nbsp;integerList.add(30);<br />
&nbsp;&nbsp;&nbsp;&nbsp;integerList.add(300);<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(getAverage(integerList)); // 111.0<br />
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Double&gt; doubleList = new ArrayList&lt;Double&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;doubleList.add(3.0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;doubleList.add(33.0);<br />
&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(getAverage(doubleList)); // 18.0<br />
&nbsp;&nbsp;}<br />
}</pre>
<br />
由于有了上界规则，上面例子中的getAverage函数允许你传递一个List&lt;Number&gt; 或一个类型变量是任何java.lang.Number子类的List。<br />
<br />
<strong>下界规则</strong><br />
关键字extends定义了一个类型变量的上界。通过使用super关键字，我们可以定义一个类型变量的下界，尽管使用的情况不多。比如，如果一个函数的参数是List&lt;? super Integer&gt;，那么意味着你可以传递一个List&lt;Integer&gt;的实例或者任何java.lang.Integer的超类(superclass)。<br />
<br />
<strong>创建泛型</strong><br />
<br />
前面的章节主要说明了如何使使用泛型，特别是集合框架中的类。现在我们开始学习如何写自己的泛型。<br />
<br />
基本上，除了声明一些你想要使用的类型变量s外，一个泛型和别的类没有什么区别。这些类型变量s位于类型后面的&lt;&gt;中。比如，下面的Point就是个泛型。一个Point对象代表了一个系统中的点，它有横坐标和纵坐标。通过使Point泛型化，你能定义一个点实例的精确程度。比如，如果一个Point对象需要非常精确，你就把Double作为类型变量。否则，