﻿<?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-The NoteBook of EricKong-随笔分类-Java</title><link>http://www.blogjava.net/jjshcc/category/45059.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 16 May 2015 01:24:48 GMT</lastBuildDate><pubDate>Sat, 16 May 2015 01:24:48 GMT</pubDate><ttl>60</ttl><item><title>JDK内置工具使用</title><link>http://www.blogjava.net/jjshcc/archive/2015/05/15/425111.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Fri, 15 May 2015 14:34:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2015/05/15/425111.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/425111.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2015/05/15/425111.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/425111.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/425111.html</trackback:ping><description><![CDATA[<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px;"><a target="_blank" href="http://blog.csdn.net/fenglibing/archive/2011/05/11/6411999.aspx" style="color: #ca0000; text-decoration: none;">JDK内置工具使用</a></p><p style="margin: 0pt 0px; padding: 0px; font-family: Arial; line-height: 26px;"><a target="_blank" href="http://blog.csdn.net/fenglibing/archive/2011/05/11/6411924.aspx" style="color: #ca0000; text-decoration: none;"><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt;"><u>一、javah<span style="font-family: 宋体;">命令</span>(C&nbsp;Header&nbsp;and&nbsp;Stub&nbsp;File&nbsp;Generator)</u></span></a></p><p style="margin: 0pt 0px; padding: 0px; font-family: Arial; line-height: 26px;"><a target="_blank" href="http://blog.csdn.net/fenglibing/archive/2011/05/11/6411932.aspx" style="color: #ca0000; text-decoration: none;"><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt;"><u>二、jps<span style="font-family: 宋体;">命令</span>(Java&nbsp;Virtual&nbsp;Machine&nbsp;Process&nbsp;Status&nbsp;Tool)</u></span></a></p><p style="margin: 0pt 0px; padding: 0px; font-family: Arial; line-height: 26px;"><a target="_blank" href="http://blog.csdn.net/fenglibing/archive/2011/05/11/6411940.aspx" style="color: #ca0000; text-decoration: none;"><span style="font-family: 'Times New Roman'; color: #800080; font-size: 10pt;"><u>三、jstack<span style="font-family: 宋体;">命令</span>(Java&nbsp;Stack&nbsp;Trace)</u></span></a></p><p style="margin: 0pt 0px; padding: 0px; font-family: Arial; line-height: 26px;"><a target="_blank" href="http://blog.csdn.net/fenglibing/archive/2011/05/11/6411951.aspx" style="color: #ca0000; text-decoration: none;"><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt;"><u>四、jstat<span style="font-family: 宋体;">命令</span>(Java&nbsp;Virtual&nbsp;Machine&nbsp;Statistics&nbsp;Monitoring&nbsp;Tool)</u></span></a></p><p style="margin: 0pt 0px; padding: 0px; font-family: Arial; line-height: 26px;"><a target="_blank" href="http://blog.csdn.net/fenglibing/archive/2011/05/11/6411953.aspx" style="color: #ca0000; text-decoration: none;"><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt;"><u>五、jmap<span style="font-family: 宋体;">命令</span>(Java&nbsp;Memory&nbsp;Map)</u></span></a></p><p style="margin: 0pt 0px; padding: 0px; font-family: Arial; line-height: 26px;"><a target="_blank" href="http://blog.csdn.net/fenglibing/archive/2011/05/11/6411958.aspx" style="color: #ca0000; text-decoration: none;"><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt;"><u>六、jinfo<span style="font-family: 宋体;">命令</span>(Java&nbsp;Configuration&nbsp;Info)</u></span></a></p><p style="margin: 0pt 0px; padding: 0px; font-family: Arial; line-height: 26px;"><a target="_blank" href="http://blog.csdn.net/fenglibing/archive/2011/05/11/6411965.aspx" style="color: #ca0000; text-decoration: none;"><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt;"><u>七、jconsole<span style="font-family: 宋体;">命令</span>(Java&nbsp;Monitoring&nbsp;and&nbsp;Management&nbsp;Console)</u></span></a></p><p style="margin: 0pt 0px; padding: 0px; font-family: Arial; line-height: 26px;"><a target="_blank" href="http://blog.csdn.net/fenglibing/archive/2011/05/11/6411969.aspx" style="color: #ca0000; text-decoration: none;"><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt;"><u>八、jvisualvm<span style="font-family: 宋体;">命令</span>(Java&nbsp;Virtual&nbsp;Machine&nbsp;Monitoring,&nbsp;Troubleshooting,&nbsp;and&nbsp;Profiling&nbsp;Tool)</u></span></a></p><p style="margin: 0pt 0px; padding: 0px; font-family: Arial; line-height: 26px;"><a target="_blank" href="http://blog.csdn.net/fenglibing/archive/2011/05/11/6411971.aspx" style="color: #ca0000; text-decoration: none;"><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt;"><u>九、jhat<span style="font-family: 宋体;">命令</span>(Java&nbsp;Heap&nbsp;Analyse&nbsp;Tool)</u></span></a></p><p style="margin: 0pt 0px; padding: 0px; font-family: Arial; line-height: 26px;"><a target="_blank" href="http://blog.csdn.net/fenglibing/archive/2011/05/11/6411974.aspx" style="color: #ca0000; text-decoration: none;"><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt;"><u>十、Jdb<span style="font-family: 宋体;">命令</span>(The&nbsp;Java&nbsp;Debugger)</u></span></a></p><p style="margin: 0pt 0px; padding: 0px; font-family: Arial; line-height: 26px;"></p><h2><a target="_blank" href="http://blog.csdn.net/fenglibing/article/details/17323515" style="color: #ca0000; text-decoration: none;"><span style="font-family: 'Times New Roman'; color: #0000ff; font-size: 10pt; text-decoration: underline;">十一、Jstatd命令(Java Statistics Monitoring Daemon)</span></a></h2>&nbsp;<img src ="http://www.blogjava.net/jjshcc/aggbug/425111.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2015-05-15 22:34 <a href="http://www.blogjava.net/jjshcc/archive/2015/05/15/425111.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java线程Dump分析工具--jstack</title><link>http://www.blogjava.net/jjshcc/archive/2015/05/15/425110.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Fri, 15 May 2015 14:24:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2015/05/15/425110.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/425110.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2015/05/15/425110.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/425110.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/425110.html</trackback:ping><description><![CDATA[<p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;"><strong>jstack</strong>用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息，如果是在64位机器上，需要指定选项"-J-d64"，Windows的jstack使用方式只支持以下的这种方式：<br />&nbsp; &nbsp; &nbsp;<strong><em>jstack [-l][F] pid</em></strong><br />&nbsp; &nbsp; &nbsp;如果java程序崩溃生成core文件，jstack工具可以用来获得core文件的java stack和native stack的信息，从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外，jstack工具还可以附属到正在运行的java程序中，看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态，jstack是非常有用的。进程处于hung死状态可以用-F强制打出stack。<br />&nbsp; &nbsp; &nbsp;<strong>dump 文件里，值得关注的线程状态有：</strong><br />&nbsp; &nbsp; &nbsp;死锁，<span style="line-height: 1.5; color: #ff0000;"><strong>Deadlock（重点关注）</strong></span><br />&nbsp; &nbsp; &nbsp;执行中，Runnable&nbsp;&nbsp;<br />&nbsp; &nbsp; &nbsp;等待资源，<strong><span style="line-height: 1.5; color: #ff0000;">Waiting on condition（重点关注）</span></strong><br />&nbsp; &nbsp; &nbsp;等待获取监视器，<strong><span style="line-height: 1.5; color: #ff0000;">Waiting on monitor entry（重点关注）</span></strong><br />&nbsp; &nbsp; &nbsp;暂停，Suspended<br />&nbsp; &nbsp; &nbsp;对象等待中，Object.wait() 或 TIMED_WAITING<br />&nbsp; &nbsp; &nbsp;阻塞，<strong><span style="line-height: 1.5; color: #ff0000;">Blocked（重点关注）</span></strong>&nbsp;<br />&nbsp; &nbsp; &nbsp;停止，Parked</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;">在摘了另一篇博客的三种场景：</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;"><strong>实例一：Waiting to lock 和 Blocked</strong></p><div style="margin: 5px 0px; widows: auto; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: navy; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;">"RMI TCP Connection(267865)-172.16.5.25" daemon prio=10 tid=0x00007fd508371000 nid=0x55ae waiting <span style="color: #0000ff; line-height: 1.5 !important;">for</span> monitor entry [0x00007fd4f8684000<span style="line-height: 1.5 !important;">]    java.lang.Thread.State: BLOCKED (on object monitor) at org.apache.log4j.Category.callAppenders(Category.java:</span>201<span style="line-height: 1.5 !important;">) </span>- waiting to lock &lt;0x00000000acf4d0c0&gt;<span style="line-height: 1.5 !important;"> (a org.apache.log4j.Logger) at org.apache.log4j.Category.forcedLog(Category.java:</span>388<span style="line-height: 1.5 !important;">) at org.apache.log4j.Category.log(Category.java:</span>853<span style="line-height: 1.5 !important;">) at org.apache.commons.logging.impl.Log4JLogger.warn(Log4JLogger.java:</span>234<span style="line-height: 1.5 !important;">) at com.tuan.core.common.lang.cache.remote.SpyMemcachedClient.get(SpyMemcachedClient.java:</span>110)</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: navy; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;">说明：<br />1）线程状态是 Blocked，阻塞状态。说明线程等待资源超时！<br />2）&#8220; waiting to lock &lt;0x00000000acf4d0c0&gt;&#8221;指，线程在等待给这个 0x00000000acf4d0c0 地址上锁（英文可描述为：trying to obtain&nbsp; 0x00000000acf4d0c0 lock）。<br />3）在 dump 日志里查找字符串 0x00000000acf4d0c0，发现有大量线程都在等待给这个地址上锁。如果能在日志里找到谁获得了这个锁（如locked &lt; 0x00000000acf4d0c0 &gt;），就可以顺藤摸瓜了。<br />4）&#8220;waiting for monitor entry&#8221;说明此线程通过 synchronized(obj) {&#8230;&#8230;} 申请进入了临界区，从而进入了下图1中的&#8220;Entry Set&#8221;队列，但该 obj 对应的 monitor 被其他线程拥有，所以本线程在 Entry Set 队列中等待。<br />5）第一行里，"RMI TCP Connection(267865)-172.16.5.25"是 Thread Name 。tid指Java Thread id。nid指native线程的id。prio是线程优先级。[0x00007fd4f8684000]是线程栈起始地址。<br /></p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;"><strong>实例二：Waiting on condition 和 TIMED_WAITING</strong></p><div style="margin: 5px 0px; widows: auto; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: navy; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;">"RMI TCP Connection(idle)" daemon prio=10 tid=0x00007fd50834e800 nid=0x56b2 waiting on condition [0x00007fd4f1a59000<span style="line-height: 1.5 !important;">]    java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) </span>- parking to wait <span style="color: #0000ff; line-height: 1.5 !important;">for</span>  &lt;0x00000000acd84de8&gt;<span style="line-height: 1.5 !important;"> (a java.util.concurrent.SynchronousQueue$TransferStack) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:</span>198<span style="line-height: 1.5 !important;">) at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:</span>424<span style="line-height: 1.5 !important;">) at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:</span>323<span style="line-height: 1.5 !important;">) at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:</span>874<span style="line-height: 1.5 !important;">) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:</span>945<span style="line-height: 1.5 !important;">) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:</span>907<span style="line-height: 1.5 !important;">) at java.lang.Thread.run(Thread.java:</span>662)</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: navy; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;">&nbsp;</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;">说明：</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;">1）&#8220;TIMED_WAITING (parking)&#8221;中的 timed_waiting 指等待状态，但这里指定了时间，到达指定的时间后自动退出等待状态；parking指线程处于挂起中。<br /><br />2）&#8220;waiting on condition&#8221;需要与堆栈中的&#8220;parking to wait for&nbsp; &lt;0x00000000acd84de8&gt; (a java.util.concurrent.SynchronousQueue$TransferStack)&#8221;结合来看。首先，本线程肯定是在等待某个条件的发生，来把自己唤醒。其次，SynchronousQueue 并不是一个队列，只是线程之间移交信息的机制，当我们把一个元素放入到 SynchronousQueue 中时必须有另一个线程正在等待接受移交的任务，因此这就是本线程在等待的条件。<br />3）别的就看不出来了。<br /><br /><span style="line-height: 1.5;"><strong>实例三：in Obejct.wait() 和 TIMED_WAITING</strong></span></p><div style="margin: 5px 0px; widows: auto; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: navy; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;">"RMI RenewClean-[172.16.5.19:28475]" daemon prio=10 tid=0x0000000041428800 nid=0xb09 in Object.wait() [0x00007f34f4bd0000<span style="line-height: 1.5 !important;">]    java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) </span>- waiting on &lt;0x00000000aa672478&gt;<span style="line-height: 1.5 !important;"> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:</span>118<span style="line-height: 1.5 !important;">) </span>- locked &lt;0x00000000aa672478&gt;<span style="line-height: 1.5 !important;"> (a java.lang.ref.ReferenceQueue$Lock) at sun.rmi.transport.DGCClient$EndpointEntry$RenewCleanThread.run(DGCClient.java:</span>516<span style="line-height: 1.5 !important;">) at java.lang.Thread.run(Thread.java:</span>662)</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: navy; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;"><span style="line-height: 1.5;">说明：</span></p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;"><span style="line-height: 1.5;">1）&#8220;TIMED_WAITING (on object monitor)&#8221;，对于本例而言，是因为本线程调用了 java.lang.Object.wait(long timeout) 而进入等待状态。</span></p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;">2）&#8220;Wait Set&#8221;中等待的线程状态就是&#8220; in Object.wait() &#8221;。当线程获得了 Monitor，进入了临界区之后，如果发现线程继续运行的条件没有满足，它则调用对象（一般就是被 synchronized 的对象）的 wait() 方法，放弃了 Monitor，进入 &#8220;Wait Set&#8221;队列。只有当别的线程在该对象上调用了 notify() 或者 notifyAll() ，&#8220; Wait Set&#8221;队列中线程才得到机会去竞争，但是只有一个线程获得对象的 Monitor，恢复到运行态。<br /><br />3）RMI RenewClean 是 DGCClient 的一部分。DGC 指的是 Distributed GC，即分布式垃圾回收。<br /><br />4）请注意，是先 locked &lt;0x00000000aa672478&gt;，后 waiting on &lt;0x00000000aa672478&gt;，之所以先锁再等同一个对象，请看下面它的代码实现：<br />static private class&nbsp; Lock { };<br />private Lock lock = new Lock();<br />public Reference&lt;? extends T&gt; remove(long timeout)<br />{<br />&nbsp;&nbsp;&nbsp; synchronized (lock) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Reference&lt;? extends T&gt; r = reallyPoll();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (r != null) return r;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (;;) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lock.wait(timeout);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r = reallyPoll();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&#8230;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />}<br />即，线程的执行中，先用 synchronized 获得了这个对象的 Monitor（对应于&nbsp; locked &lt;0x00000000aa672478&gt; ）；当执行到 lock.wait(timeout);，线程就放弃了 Monitor 的所有权，进入&#8220;Wait Set&#8221;队列（对应于&nbsp; waiting on &lt;0x00000000aa672478&gt; ）。<br />5）从堆栈信息看，是正在清理 remote references to remote objects ，引用的租约到了，分布式垃圾回收在逐一清理呢。</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;">参考：</p><p style="font-size: 13px; line-height: 19px; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; widows: auto; background-color: #ffffff;">命令汇总：<span style="line-height: 1.5; text-decoration: underline;">http://blog.csdn.net/fenglibing/article/details/6411940</span><br />三种实例：<span style="line-height: 1.5; text-decoration: underline;">http://www.cnblogs.com/zhengyun_ustc/archive/2013/01/06/dumpanalysis.html</span></p><img src ="http://www.blogjava.net/jjshcc/aggbug/425110.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2015-05-15 22:24 <a href="http://www.blogjava.net/jjshcc/archive/2015/05/15/425110.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解</title><link>http://www.blogjava.net/jjshcc/archive/2015/03/20/423661.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Fri, 20 Mar 2015 01:46:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2015/03/20/423661.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/423661.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2015/03/20/423661.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/423661.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/423661.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JDK本身提供了很多方便的JVM性能调优监控工具，除了集成式的VisualVM和jConsole外，还有jps、jstack、jmap、jhat、jstat等小巧的工具，本博客希望能起抛砖引玉之用，让大家能开始对JVM性能调优的常用工具有所了解。&nbsp; &nbsp; 现实企业级Java开发中，有时候我们会碰到下面这些问题：OutOfMemoryError，内存不足内存泄露线程死锁锁争用（Lo...&nbsp;&nbsp;<a href='http://www.blogjava.net/jjshcc/archive/2015/03/20/423661.html'>阅读全文</a><img src ="http://www.blogjava.net/jjshcc/aggbug/423661.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2015-03-20 09:46 <a href="http://www.blogjava.net/jjshcc/archive/2015/03/20/423661.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AVAMAIL发送邮件给多个收件人</title><link>http://www.blogjava.net/jjshcc/archive/2015/02/09/422828.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Mon, 09 Feb 2015 05:05:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2015/02/09/422828.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/422828.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2015/02/09/422828.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/422828.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/422828.html</trackback:ping><description><![CDATA[<div>String[] str = {};</div><div>InternetAddress[] address=new InternetAddress[amount];</div><div>for (int i=0;i&lt;str.length;i++){</div><div>address[i]=new InternetAddress(str[i]]);</div><div>}</div><div>msg.setRecipients(Message.RecipientType.TO,address);</div><img src ="http://www.blogjava.net/jjshcc/aggbug/422828.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2015-02-09 13:05 <a href="http://www.blogjava.net/jjshcc/archive/2015/02/09/422828.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java安全通信：HTTPS与SSL</title><link>http://www.blogjava.net/jjshcc/archive/2015/01/27/422462.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Tue, 27 Jan 2015 02:28:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2015/01/27/422462.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/422462.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2015/01/27/422462.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/422462.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/422462.html</trackback:ping><description><![CDATA[<p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">1. HTTPS概念</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;1）简介&nbsp;&nbsp;&nbsp;</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HTTPS（全称：Hypertext Transfer Protocol over Secure Socket Layer），是以安全为目标的<a href="http://baike.baidu.com/view/9472.htm" target="_blank" style="color: #1a8bc8; text-decoration: none;">HTTP</a>通道，简单讲是HTTP的安全版。即HTTP下加入SSL层，HTTPS的安全基础是SSL，因此加密的详细内容就需要SSL。这个系统的最初研发由网景公司进行，提供了身份验证与加密<a href="http://baike.baidu.com/view/20429.htm" target="_blank" style="color: #1a8bc8; text-decoration: none;">通讯</a>方法，现在它被广泛用于<a href="http://baike.baidu.com/view/7833.htm" target="_blank" style="color: #1a8bc8; text-decoration: none;">万维网</a>上安全敏感的通讯，例如交易支付方面。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2）HTTPS和HTTP的区别</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　a. https协议需要到ca申请证书，一般免费证书很少，需要交费。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　b. http是<a href="http://baike.baidu.com/view/468465.htm" target="_blank" style="color: #1a8bc8; text-decoration: none;">超文本传输协议</a>，信息是明文传输；https 则是具有<a href="http://baike.baidu.com/view/421194.htm" target="_blank" style="color: #1a8bc8; text-decoration: none;">安全性</a>的ssl加密传输协议。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　c. http和https使用的是完全不同的连接方式，用的端口也不一样，前者是80，后者是443。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">d. http的连接很简单，是无状态的；HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的<a href="http://baike.baidu.com/view/16603.htm" target="_blank" style="color: #1a8bc8; text-decoration: none;">网络协议</a>，比http协议安全。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3）HTTPS的作用</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 它的主要作用可以分为两种：一种是建立一个<a href="http://baike.baidu.com/view/17249.htm" target="_blank" style="color: #1a8bc8; text-decoration: none;">信息安全</a>通道，来保证数据传输的安全；另一种就是确认网站的真实性。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　a． 一般意义上的https，就是服务器有一个证书。主要目的是保证服务器就是他声称的服务器，这个跟第一点一样；<a href="http://baike.baidu.com/view/1087294.htm" target="_blank" style="color: #1a8bc8; text-decoration: none;">服务端</a>和客户端之间的所有<a href="http://baike.baidu.com/view/20429.htm" target="_blank" style="color: #1a8bc8; text-decoration: none;">通讯</a>，都是加密的。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　b. 具体讲，是客户端产生一个对称的<a href="http://baike.baidu.com/view/934.htm" target="_blank" style="color: #1a8bc8; text-decoration: none;">密钥</a>，通过服务器的证书来交换密钥，即一般意义上的握手过程。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　c. 接下来所有的信息往来就都是加密的。第三方即使截获，也没有任何意义，因为他没有密钥，当然篡改也就没有什么意义了。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　d．少许对客户端有要求的情况下，会要求客户端也必须有一个证书。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">这里客户端证书，其实就类似表示个人信息的时候，除了用户名/密码，还有一个CA 认证过的身份。因为个人证书一般来说是别人无法模拟的，所有这样能够更深的确认自己的身份。目前少数个人银行的专业版是这种做法，具体证书可能是拿U盘（即U盾）作为一个备份的载体。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">&nbsp;</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">2.SSL简介</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　1）简介</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　SSL (Secure Socket Layer)为Netscape所研发，用以保障在Internet上数据传输之安全，利用数据加密(Encryption)技术，可确保数据在网络上之传输过程中不会被截取及窃听。它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输。SSL协议位于TCP/IP协议与各种应用层协议之间，为数据通讯提供安全支持。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　2）SSL提供的服务</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　a.认证用户和服务器，确保数据发送到正确的<a href="http://baike.baidu.com/view/285153.htm" target="_blank" style="color: #1a8bc8; text-decoration: none;">客户机</a>和服务器</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　b.加密数据以防止数据中途被窃取</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　c.维护数据的完整性，确保数据在传输过程中不被改变。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　3) SSL协议的握手过程</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　SSL 协议既用到了公钥加密技术又用到了对称加密技术，对称加密技术虽然比公钥加密技术的速度快，可是公钥加密技术提供了更好的身份认证技术。SSL 的握手协议非常有效的让客户和服务器之间完成相互之间的身份认证，其主要过程如下：</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　&#9312;客户端的浏览器向服务器传送客户端SSL 协议的版本号，加密算法的种类，产生的随机数，以及其他服务器和客户端之间通讯所需要的各种信息。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　&#9313;服务器向客户端传送SSL 协议的版本号，加密算法的种类，随机数以及其他相关信息，同时服务器还将向客户端传送自己的证书。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　&#9314;客户利用服务器传过来的信息验证服务器的合法性，服务器的合法性包括：证书是否过期，发行服务器证书的CA 是否可靠，发行者证书的公钥能否正确解开服务器证书的&#8220;发行者的数字签名&#8221;，服务器证书上的域名是否和服务器的实际域名相匹配。如果合法性验证没有通过，通讯将断开；如果合法性验证通过，将继续进行第四步。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　&#9315;用户端随机产生一个用于后面通讯的&#8220;对称密码&#8221;，然后用服务器的公钥（服务器的公钥从步骤&#9313;中的服务器的证书中获得）对其加密，然后传给服务器。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　&#9316;服务器用私钥解密&#8220;对称密码&#8221;(此处的公钥和私钥是相互关联的，公钥加密的数据只能用私钥解密，私钥只在服务器端保留。详细请参看：&nbsp;<a href="http://zh.wikipedia.org/wiki/RSA%E7%AE%97%E6%B3%95" style="color: #1a8bc8; text-decoration: none;">http://zh.wikipedia.org/wiki/RSA%E7%AE%97%E6%B3%95</a>)，然后用其作为服务器和客户端的&#8220;通话密码&#8221;加解密通讯。同时在SSL 通讯过程中还要完成数据通讯的完整性，防止数据通讯中的任何变化。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　&#9317;客户端向服务器端发出信息，指明后面的数据通讯将使用的步骤&#9316;中的主密码为对称密钥，同时通知服务器客户端的握手过程结束。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　&#9318;服务器向客户端发出信息，指明后面的数据通讯将使用的步骤&#9316;中的主密码为对称密钥，同时通知客户端服务器端的握手过程结束。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　&#9319;SSL 的握手部分结束，SSL 安全通道的数据通讯开始，客户和服务器开始使用相同的对称密钥进行数据通讯，同时进行通讯完整性的检验。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">&nbsp; &nbsp; &nbsp; &nbsp;<img src="http://pic002.cnblogs.com/images/2012/267603/2012022815142423.gif" alt="" style="border: 0px;" /></p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">&nbsp;</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">3.配置服务器端证书</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　为了能实施SSL，一个web服务器对每个接受安全连接的外部接口(IP 地址)必须要有相应的证书(Certificate)。关于这个设计的理论是一个服务器必须提供某种合理的保证以证明这个服务器的主人就是你所认为的那个人。这个证书要陈述与这个网站相关联的公司，以及这个网站的所有者或系统管理员的一些基本联系信息。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　这个证书由所有人以密码方式签字，其他人非常难伪造。对于进行电子商务(e-commerce)的网站，或其他身份认证至关重要的任何商业交易，认证书要向大家所熟知的认证权威(Certificate Authority (CA))如VeriSign或Thawte来购买。这样的证书可用电子技术证明属实。实际上，认证权威单位会担保它发出的认证书的真实性，如果你信任发出认证书的认证权威单位的话，你就可以相信这个认证书是有效的。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　关于权威证书的申请，请参考：<a href="http://www.cnblogs.com/mikespook/archive/2004/12/22/80591.aspx" style="color: #1a8bc8; text-decoration: none;">http://www.cnblogs.com/mikespook/archive/2004/12/22/80591.aspx</a></p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　在许多情况下，认证并不是真正使人担忧的事。系统管理员或许只想要保证被服务器传送和接收的数据是秘密的，不会被连接线上的偷窃者盗窃到。庆幸的是，Java提供相对简单的被称为keytool的命令行工具，可以简单地产生&#8220;自己签名&#8221;的证书。自己签名的证书只是用户产生的证书，没有正式在大家所熟知的认证权威那里注册过，因此不能确保它的真实性。但却能保证数据传输的安全性。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　用Tomcat来配置SSL主要有下面这么两大步骤：</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　1)生成证书</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　a. 在命令行下执行：</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　%Java_home%\bin\keytool -genkey -alias tomcat -keyalg RSA</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　在此命令中，keytool是JDK自带的产生证书的工具。把RSA运算法则作为主要安全运算法则，这保证了与其它服务器和组件的兼容性。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">这个命令会在用户的home directory产生一个叫做" .keystore " 的新文件。在执行后，你首先被要求出示keystore密码。Tomcat使用的默认密码是" changeit "(全都是小写字母)，如果你愿意，你可以指定你自己的密码。你还需要在server.xml配置文件里指定自己的密码，这在以后会有描述。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　b .你会被要求出示关于这个认证书的一般性信息，如公司，联系人名称，等等。这些信息会显示给那些试图访问你程序里安全网页的用户，以确保这里提供的信息与他们期望的相对应。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　c.你会被要求出示密钥(key)密码，也就是这个认证书所特有的密码(与其它的储存在同一个keystore文件里的认证书不同)。你必须在这里使用与keystore密码相同的密码。(目前，keytool会提示你按ENTER键会自动帮你做这些)。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　如果一切顺利，你现在就拥有了一个可以被你的服务器使用的有认证书的keystore文件。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　2) 配置tomcat</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　第二个大步骤是把secure socket配置在$CATALINA_HOME/conf/server.xml文件里。$CATALINA_HOME代表安装Tomcat的目录。一个例子是SSL连接器的元素被包括在和Tomcat一起安装的缺省server.xml文件里。它看起来象是这样：</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">$CATALINA_HOME/conf/server.xml</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #0000ff; line-height: 1.5 !important;">&lt;</span><span style="color: #800000; line-height: 1.5 !important;"> -- </span><span style="color: #ff0000; line-height: 1.5 !important;">Define a SSL Coyote HTTP/1.1 Connector on port 8443 --</span><span style="color: #0000ff; line-height: 1.5 !important;">&gt;</span><br /><br /><span style="color: #0000ff; line-height: 1.5 !important;">&lt;</span><span style="color: #800000; line-height: 1.5 !important;"> !--<br /><br /></span><span style="color: #ff0000; line-height: 1.5 !important;">&lt; Connector<br /><br />port</span><span style="color: #0000ff; line-height: 1.5 !important;">="8443"</span><span style="color: #ff0000; line-height: 1.5 !important;"> minProcessors</span><span style="color: #0000ff; line-height: 1.5 !important;">="5"</span><span style="color: #ff0000; line-height: 1.5 !important;"> maxProcessors</span><span style="color: #0000ff; line-height: 1.5 !important;">="75"</span><span style="color: #ff0000; line-height: 1.5 !important;"><br /><br />enableLookups</span><span style="color: #0000ff; line-height: 1.5 !important;">="true"</span><span style="color: #ff0000; line-height: 1.5 !important;"> disableUploadTimeout</span><span style="color: #0000ff; line-height: 1.5 !important;">="true"</span><span style="color: #ff0000; line-height: 1.5 !important;"><br /><br />acceptCount</span><span style="color: #0000ff; line-height: 1.5 !important;">="100"</span><span style="color: #ff0000; line-height: 1.5 !important;"> debug</span><span style="color: #0000ff; line-height: 1.5 !important;">="0"</span><span style="color: #ff0000; line-height: 1.5 !important;"> scheme</span><span style="color: #0000ff; line-height: 1.5 !important;">="https"</span><span style="color: #ff0000; line-height: 1.5 !important;"> secure</span><span style="color: #0000ff; line-height: 1.5 !important;">="true"</span><span style="color: #ff0000; line-height: 1.5 !important;">;<br /><br />clientAuth</span><span style="color: #0000ff; line-height: 1.5 !important;">="false"</span><span style="color: #ff0000; line-height: 1.5 !important;"> sslProtocol</span><span style="color: #0000ff; line-height: 1.5 !important;">="TLS"</span><span style="color: #0000ff; line-height: 1.5 !important;">/&gt;</span><br /><br />--&gt;</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　Connector元素本身，其默认形式是被注释掉的(commented out)，所以需要把它周围的注释标志删除掉。然后，可以根据需要客户化(自己设置)特定的属性。一般需要增加一下keystoreFile和keystorePass两个属性，指定你存放证书的路径（如：keystoreFile="C:/.keystore"）和刚才设置的密码（如：keystorePass="123456"）。关于其它各种选项的详细信息，可查阅Server Configuration Reference。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　在完成这些配置更改后，必须象重新启动Tomcat，然后你就可以通过SSL访问Tomcat支持的任何web应用程序。只不过指令需要像下面这样：https://localhost:8443</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">&nbsp;</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">4.客户端代码实现</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　在Java中要访问Https链接时，会用到一个关键类<strong>HttpsURLConnection</strong>；参见如下实现代码：</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;">        <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 创建URL对象</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        URL myURL = <span style="color: #0000ff; line-height: 1.5 !important;">new</span> URL("https://www.sun.com");<br /> <br />        <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 创建HttpsURLConnection对象，并设置其SSLSocketFactory对象</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        HttpsURLConnection httpsConn = (HttpsURLConnection) myURL.openConnection();<br /> <br />        <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 取得该连接的输入流，以读取响应内容</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        InputStreamReader insr = <span style="color: #0000ff; line-height: 1.5 !important;">new</span> InputStreamReader(httpsConn.getInputStream());<br /> <br />        <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 读取服务器的响应内容并显示</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        <span style="color: #0000ff; line-height: 1.5 !important;">int</span> respInt = insr.read();<br />        <span style="color: #0000ff; line-height: 1.5 !important;">while</span> (respInt != -1) {<br />            System.out.print((<span style="color: #0000ff; line-height: 1.5 !important;">char</span>) respInt);<br />            respInt = insr.read();<br />        }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　在取得connection的时候和正常浏览器访问一样，仍然会<strong>验证服务端的证书是否被信任</strong>（权威机构发行或者被权威机构签名）；如果服务端证书不被信任，则默认的实现就会有问题，一般来说，用<strong><span style="line-height: 1.5; color: #ff0000;">SunJSSE</span></strong>会抛如下异常信息：</p><div style="color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px; background-color: #ffffff;"><div><div id="highlighter_339068" nogutter=""  csharp"="" style="width: 941px; margin: 1em 0px !important; position: relative !important; overflow: auto !important; font-size: 1em !important;"><table border="0" cellpadding="0" cellspacing="0" style="border-style: solid; border-color: silver; width: 941px; border-collapse: collapse; word-break: break-word; border-radius: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 12px !important; min-height: inherit !important; background: none !important;"><tbody style="border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: inherit !important; background: none !important;"><tr style="border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: inherit !important; background: none !important;"><td style="color: #454545; border-style: solid; border-color: silver; padding: 3px; border-collapse: collapse; border-radius: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: inherit !important; background: none !important;"><div style="border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; position: relative !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: inherit !important; background: none !important;"><div number1="" index0=""  alt2"="" style="border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.8em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding-right: 1em !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: inherit !important; background: none #f4f4f4 !important;"><code plain"="" style="white-space: pre-wrap; border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.8em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; min-height: inherit !important; color: #000000 !important; background: none !important;">javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building&nbsp;</code></div></div></td></tr></tbody></table></div></div><div><div id="highlighter_599218" nogutter=""  csharp"="" style="width: 941px; margin: 1em 0px !important; position: relative !important; overflow: auto !important; font-size: 1em !important;"><table border="0" cellpadding="0" cellspacing="0" style="border-style: solid; border-color: silver; width: 941px; border-collapse: collapse; word-break: break-word; border-radius: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 12px !important; min-height: inherit !important; background: none !important;"><tbody style="border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: inherit !important; background: none !important;"><tr style="border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: inherit !important; background: none !important;"><td style="color: #454545; border-style: solid; border-color: silver; padding: 3px; border-collapse: collapse; border-radius: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: inherit !important; background: none !important;"><div style="border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; position: relative !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: inherit !important; background: none !important;"><div number1="" index0=""  alt2"="" style="border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.8em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding-right: 1em !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: inherit !important; background: none #f4f4f4 !important;"><code plain"="" style="white-space: pre-wrap; border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.8em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; min-height: inherit !important; color: #000000 !important; background: none !important;">failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target</code></div></div></td></tr></tbody></table></div></div></div><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　上面提到SunJSSE，JSSE（Java Secure Socket Extension）是实现Internet安全通信的一系列包的集合。它是一个SSL和TLS的纯Java实现，可以透明地提供数据加密、服务器认证、信息完整性等功能，可以使我们像使用普通的套接字一样使用JSSE建立的安全套接字。JSSE是一个开放的标准，不只是Sun公司才能实现一个SunJSSE，事实上其他公司有自己实现的JSSE，然后通过JCA就可以在JVM中使用。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　关于JSSE的详细信息参考官网Reference：<a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html" style="color: #1a8bc8; text-decoration: none;">http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html</a>；<br />　　以及Java Security Guide：<a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/" style="color: #1a8bc8; text-decoration: none;">http://java.sun.com/j2se/1.5.0/docs/guide/security/</a>；</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　在深入了解JSSE之前，需要了解一个有关Java安全的概念：客户端的TrustStore文件。客户端的TrustStore文件中保存着被客户端所信任的服务器的证书信息。客户端在进行SSL连接时，JSSE将根据这个文件中的证书决定是否信任服务器端的证书。在SunJSSE中，有一个信任管理器类负责决定是否信任远端的证书，这个类有如下的处理规则：<br />1)若系统属性<strong>javax.net.sll.trustStore</strong>指定了TrustStore文件，那么信任管理器就去jre安装路径下的lib/security/目录中寻找并使用这个文件来检查证书。<br />2)若该系统属性没有指定TrustStore文件，它就会去jre安装路径下寻找默认的TrustStore文件，这个文件的相对路径为：lib/security/<strong>jssecacerts</strong>。<br />3)若jssecacerts不存在，但是cacerts存在（它随J2SDK一起发行，含有数量有限的可信任的基本证书），那么这个默认的TrustStore文件就是lib/security/<strong>cacerts</strong>。</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　那遇到这种情况，怎么处理呢？有以下两种方案：<br />　　1)按照以上信任管理器的规则，<strong>将服务端的公钥导入到jssecacerts</strong>，或者是在系统属性中设置要加载的trustStore文件的路径；证书导入可以用如下命令：keytool -import -file src_cer_file &#8211;keystore dest_cer_store；至于证书可以通过浏览器导出获得；<br />　　2)、实现自己的证书信任管理器类，比如<strong>MyX509TrustManager</strong>，该类必须实现X509TrustManager接口中的三个method；然后在HttpsURLConnection中加载自定义的类，可以参见如下两个代码片段，其一为自定义证书信任管理器，其二为connect时的代码：</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="color: #0000ff; line-height: 1.5 !important;">package</span> test;<br /><span style="color: #0000ff; line-height: 1.5 !important;">import</span> java.io.FileInputStream;<br /><span style="color: #0000ff; line-height: 1.5 !important;">import</span> java.security.KeyStore;<br /><span style="color: #0000ff; line-height: 1.5 !important;">import</span> java.security.cert.CertificateException;<br /><span style="color: #0000ff; line-height: 1.5 !important;">import</span> java.security.cert.X509Certificate;<br /><span style="color: #0000ff; line-height: 1.5 !important;">import</span> javax.net.ssl.TrustManager;<br /><span style="color: #0000ff; line-height: 1.5 !important;">import</span> javax.net.ssl.TrustManagerFactory;<br /><span style="color: #0000ff; line-height: 1.5 !important;">import</span> javax.net.ssl.X509TrustManager;<br /><span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">class</span> MyX509TrustManager <span style="color: #0000ff; line-height: 1.5 !important;">implements</span> X509TrustManager {<br />    <span style="color: #008000; line-height: 1.5 !important;">/*</span><span style="color: #008000; line-height: 1.5 !important;"><br />     * The default X509TrustManager returned by SunX509.  We'll delegate<br />     * decisions to it, and fall back to the logic in this class if the<br />     * default X509TrustManager doesn't trust it.<br />     </span><span style="color: #008000; line-height: 1.5 !important;">*/</span><br />    X509TrustManager sunJSSEX509TrustManager;<br />    MyX509TrustManager() <span style="color: #0000ff; line-height: 1.5 !important;">throws</span> Exception {<br />        <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> create a "default" JSSE X509TrustManager.</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        KeyStore ks = KeyStore.getInstance("JKS");<br />        ks.load(<span style="color: #0000ff; line-height: 1.5 !important;">new</span> FileInputStream("trustedCerts"),<br />            "passphrase".toCharArray());<br />        TrustManagerFactory tmf =<br />        TrustManagerFactory.getInstance("SunX509", "SunJSSE");<br />        tmf.init(ks);<br />        TrustManager tms [] = tmf.getTrustManagers();<br />        <span style="color: #008000; line-height: 1.5 !important;">/*</span><span style="color: #008000; line-height: 1.5 !important;"><br />         * Iterate over the returned trustmanagers, look<br />         * for an instance of X509TrustManager.  If found,<br />         * use that as our "default" trust manager.<br />         </span><span style="color: #008000; line-height: 1.5 !important;">*/</span><br />        <span style="color: #0000ff; line-height: 1.5 !important;">for</span> (<span style="color: #0000ff; line-height: 1.5 !important;">int</span> i = 0; i &lt; tms.length; i++) {<br />            <span style="color: #0000ff; line-height: 1.5 !important;">if</span> (tms[i] <span style="color: #0000ff; line-height: 1.5 !important;">instanceof</span> X509TrustManager) {<br />                sunJSSEX509TrustManager = (X509TrustManager) tms[i];<br />                <span style="color: #0000ff; line-height: 1.5 !important;">return</span>;<br />            }<br />        }<br />        <span style="color: #008000; line-height: 1.5 !important;">/*</span><span style="color: #008000; line-height: 1.5 !important;"><br />         * Find some other way to initialize, or else we have to fail the<br />         * constructor.<br />         </span><span style="color: #008000; line-height: 1.5 !important;">*/</span><br />        <span style="color: #0000ff; line-height: 1.5 !important;">throw</span> <span style="color: #0000ff; line-height: 1.5 !important;">new</span> Exception("Couldn't initialize");<br />    }<br />    <span style="color: #008000; line-height: 1.5 !important;">/*</span><span style="color: #008000; line-height: 1.5 !important;"><br />     * Delegate to the default trust manager.<br />     </span><span style="color: #008000; line-height: 1.5 !important;">*/</span><br />    <span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">void</span> checkClientTrusted(X509Certificate[] chain, String authType)<br />                <span style="color: #0000ff; line-height: 1.5 !important;">throws</span> CertificateException {<br />        <span style="color: #0000ff; line-height: 1.5 !important;">try</span> {<br />            sunJSSEX509TrustManager.checkClientTrusted(chain, authType);<br />        } <span style="color: #0000ff; line-height: 1.5 !important;">catch</span> (CertificateException excep) {<br />            <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> do any special handling here, or rethrow exception.</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        }<br />    }<br />    <span style="color: #008000; line-height: 1.5 !important;">/*</span><span style="color: #008000; line-height: 1.5 !important;"><br />     * Delegate to the default trust manager.<br />     </span><span style="color: #008000; line-height: 1.5 !important;">*/</span><br />    <span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">void</span> checkServerTrusted(X509Certificate[] chain, String authType)<br />                <span style="color: #0000ff; line-height: 1.5 !important;">throws</span> CertificateException {<br />        <span style="color: #0000ff; line-height: 1.5 !important;">try</span> {<br />            sunJSSEX509TrustManager.checkServerTrusted(chain, authType);<br />        } <span style="color: #0000ff; line-height: 1.5 !important;">catch</span> (CertificateException excep) {<br />            <span style="color: #008000; line-height: 1.5 !important;">/*</span><span style="color: #008000; line-height: 1.5 !important;"><br />             * Possibly pop up a dialog box asking whether to trust the<br />             * cert chain.<br />             </span><span style="color: #008000; line-height: 1.5 !important;">*/</span><br />        }<br />    }<br />    <span style="color: #008000; line-height: 1.5 !important;">/*</span><span style="color: #008000; line-height: 1.5 !important;"><br />     * Merely pass this through.<br />     </span><span style="color: #008000; line-height: 1.5 !important;">*/</span><br />    <span style="color: #0000ff; line-height: 1.5 !important;">public</span> X509Certificate[] getAcceptedIssuers() {<br />        <span style="color: #0000ff; line-height: 1.5 !important;">return</span> sunJSSEX509TrustManager.getAcceptedIssuers();<br />    }<br />}<br />        <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 创建SSLContext对象，并使用我们指定的信任管理器初始化</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        TrustManager[] tm = { <span style="color: #0000ff; line-height: 1.5 !important;">new</span> MyX509TrustManager() };<br />        SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");<br />        sslContext.init(<span style="color: #0000ff; line-height: 1.5 !important;">null</span>, tm, <span style="color: #0000ff; line-height: 1.5 !important;">new</span> java.security.SecureRandom());<br />        <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 从上述SSLContext对象中得到SSLSocketFactory对象</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        SSLSocketFactory ssf = sslContext.getSocketFactory();<br />        <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 创建URL对象</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        URL myURL = <span style="color: #0000ff; line-height: 1.5 !important;">new</span> URL("https://ebanks.gdb.com.cn/sperbank/perbankLogin.jsp");<br />        <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 创建HttpsURLConnection对象，并设置其SSLSocketFactory对象</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        HttpsURLConnection httpsConn = (HttpsURLConnection) myURL.openConnection();<br />        httpsConn.setSSLSocketFactory(ssf);<br />        <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 取得该连接的输入流，以读取响应内容</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        InputStreamReader insr = <span style="color: #0000ff; line-height: 1.5 !important;">new</span> InputStreamReader(httpsConn.getInputStream());<br />        <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 读取服务器的响应内容并显示</span><span style="color: #008000; line-height: 1.5 !important;"><br /></span>        <span style="color: #0000ff; line-height: 1.5 !important;">int</span> respInt = insr.read();<br />        <span style="color: #0000ff; line-height: 1.5 !important;">while</span> (respInt != -1) {<br />            System.out.print((<span style="color: #0000ff; line-height: 1.5 !important;">char</span>) respInt);<br />            respInt = insr.read();<br />        }</pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="border: none !important;" /></a></span></div></div><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　对于以上两种实现方式，各有各的优点，第一种方式<strong>不会破坏JSSE的安全性</strong>，但是要手工导入证书，如果服务器很多，那每台服务器的JRE都必须做相同的操作；第二种方式<strong>灵活性更高</strong>，但是要小心实现，否则可能会留下安全隐患；</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">&nbsp;</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　参考文献：&nbsp;　　　　&nbsp;　　</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　http://baike.baidu.com/view/14121.htm</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　http://zh.wikipedia.org/wiki/RSA%E7%AE%97%E6%B3%95</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　http://blog.csdn.net/sfdev/article/details/2957240</p><p style="line-height: 19.5px; margin-top: 10px; margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;">　　http://blog.csdn.net/cyberexp2008/article/details/6695691</p><img src ="http://www.blogjava.net/jjshcc/aggbug/422462.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2015-01-27 10:28 <a href="http://www.blogjava.net/jjshcc/archive/2015/01/27/422462.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet作为代理实现跨域访问</title><link>http://www.blogjava.net/jjshcc/archive/2015/01/26/422450.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Mon, 26 Jan 2015 09:32:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2015/01/26/422450.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/422450.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2015/01/26/422450.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/422450.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/422450.html</trackback:ping><description><![CDATA[<div>就是在前台中调用proxy程序的servlet，设置参数servletName和其它参数。代理程序会将该请求发送到目的地址的名称为servletName的servlet中去，并将其它参数作为请求的参数，在得到结果后，将内容原样输出到请求页面。</div><div>import java.io.IOException;</div><div>import java.io.InputStream;</div><div>import java.io.OutputStream;</div><div>import java.io.UnsupportedEncodingException;</div><div>import java.net.HttpURLConnection;</div><div>import java.net.MalformedURLException;</div><div>import java.net.URL;</div><div>import java.net.URLEncoder;</div><div>import java.util.Iterator;</div><div>import java.util.Map;</div><div>import java.util.Map.Entry;</div><div></div><div>import javax.servlet.ServletException;</div><div>import javax.servlet.http.HttpServlet;</div><div>import javax.servlet.http.HttpServletRequest;</div><div>import javax.servlet.http.HttpServletResponse;</div><div></div><div>public class ProxyServlet extends HttpServlet {</div><div><span style="white-space:pre">	</span>private String url;</div><div></div><div><span style="white-space:pre">	</span>/**</div><div><span style="white-space:pre">	</span> * 对servlet进行请求处理，并将结果在指定输出流中输出</div><div><span style="white-space:pre">	</span> *&nbsp;</div><div><span style="white-space:pre">	</span> * @param os</div><div><span style="white-space:pre">	</span> * @param servletName</div><div><span style="white-space:pre">	</span> * @param parm</div><div><span style="white-space:pre">	</span> * @throws IOException</div><div><span style="white-space:pre">	</span> * @throws MalformedURLException</div><div><span style="white-space:pre">	</span> */</div><div><span style="white-space:pre">	</span>private void process(HttpServletRequest req, HttpServletResponse resp,</div><div><span style="white-space:pre">			</span>String[] target) throws MalformedURLException, IOException {</div><div><span style="white-space:pre">		</span>// 取得连接</div><div><span style="white-space:pre">		</span>HttpURLConnection huc = (HttpURLConnection) new URL(url + target[0])</div><div><span style="white-space:pre">				</span>.openConnection();</div><div></div><div><span style="white-space:pre">		</span>// 设置连接属性</div><div><span style="white-space:pre">		</span>huc.setDoOutput(true);</div><div><span style="white-space:pre">		</span>huc.setRequestMethod("POST");</div><div><span style="white-space:pre">		</span>huc.setUseCaches(false);</div><div><span style="white-space:pre">		</span>huc.setInstanceFollowRedirects(true);</div><div><span style="white-space:pre">		</span>huc.setRequestProperty("Content-Type",</div><div><span style="white-space:pre">				</span>"application/x-www-form-urlencoded");</div><div><span style="white-space:pre">		</span>huc.connect();</div><div></div><div><span style="white-space:pre">		</span>// 往目标servlet中提供参数</div><div><span style="white-space:pre">		</span>OutputStream targetOS = huc.getOutputStream();</div><div><span style="white-space:pre">		</span>targetOS.write(target[1].getBytes());</div><div><span style="white-space:pre">		</span>targetOS.flush();</div><div><span style="white-space:pre">		</span>targetOS.close();</div><div></div><div><span style="white-space:pre">		</span>// 取得页面输出,并设置页面编码及缓存设置</div><div><span style="white-space:pre">		</span>resp.setContentType(huc.getContentType());</div><div><span style="white-space:pre">		</span>resp.setHeader("Cache-Control", huc.getHeaderField("Cache-Control"));</div><div><span style="white-space:pre">		</span>resp.setHeader("Pragma", huc.getHeaderField("Pragma"));</div><div><span style="white-space:pre">		</span>resp.setHeader("Expires", huc.getHeaderField("Expires"));</div><div><span style="white-space:pre">		</span>OutputStream os = resp.getOutputStream();</div><div></div><div><span style="white-space:pre">		</span>// 将目标servlet的输入流直接往页面输出</div><div><span style="white-space:pre">		</span>InputStream targetIS = huc.getInputStream();</div><div><span style="white-space:pre">		</span>int r;</div><div><span style="white-space:pre">		</span>while ((r = targetIS.read()) != -1) {</div><div><span style="white-space:pre">			</span>os.write(r);</div><div><span style="white-space:pre">		</span>}</div><div><span style="white-space:pre">		</span>targetIS.close();</div><div><span style="white-space:pre">		</span>os.flush();</div><div><span style="white-space:pre">		</span>os.close();</div><div></div><div><span style="white-space:pre">		</span>huc.disconnect();</div><div><span style="white-space:pre">	</span>}</div><div></div><div><span style="white-space:pre">	</span>/**</div><div><span style="white-space:pre">	</span> * 将参数中的目标分离成由目标servlet名称和参数组成的数组</div><div><span style="white-space:pre">	</span> *&nbsp;</div><div><span style="white-space:pre">	</span> * @param queryString</div><div><span style="white-space:pre">	</span> * @return</div><div><span style="white-space:pre">	</span> * @throws UnsupportedEncodingException</div><div><span style="white-space:pre">	</span> */</div><div><span style="white-space:pre">	</span>private String[] parse(Map map) throws UnsupportedEncodingException {</div><div><span style="white-space:pre">		</span>String[] arr = { "", "" };</div><div><span style="white-space:pre">		</span>Iterator iter = map.entrySet().iterator();</div><div><span style="white-space:pre">		</span>while (iter.hasNext()) {</div><div><span style="white-space:pre">			</span>Map.Entry me = (Entry) iter.next();</div><div><span style="white-space:pre">			</span>String[] varr = (String[]) me.getValue();</div><div><span style="white-space:pre">			</span>if ("servletName".equals(me.getKey())) {</div><div><span style="white-space:pre">				</span>// 取出servlet名称</div><div><span style="white-space:pre">				</span>arr[0] = varr[0];</div><div><span style="white-space:pre">			</span>} else {</div><div><span style="white-space:pre">				</span>// 重新组装参数字符串</div><div><span style="white-space:pre">				</span>for (int i = 0; i &lt; varr.length; i++) {</div><div><span style="white-space:pre">					</span>// 参数需要进行转码，实现字符集的统一</div><div><span style="white-space:pre">					</span>arr[1] += "&amp;" + me.getKey() + "="</div><div><span style="white-space:pre">							</span>+ URLEncoder.encode(varr[i], "utf-8");</div><div><span style="white-space:pre">				</span>}</div><div><span style="white-space:pre">			</span>}</div><div><span style="white-space:pre">		</span>}</div><div><span style="white-space:pre">		</span>arr[1] = arr[1].replaceAll("^&amp;", "");</div><div><span style="white-space:pre">		</span>return arr;</div><div><span style="white-space:pre">	</span>}</div><div></div><div><span style="white-space:pre">	</span>@Override</div><div><span style="white-space:pre">	</span>public void init() throws ServletException {</div><div><span style="white-space:pre">		</span>// 设置目标服务器地址</div><div><span style="white-space:pre">		</span>url = this.getInitParameter("url");</div><div><span style="white-space:pre">		</span>if (!url.endsWith("/"))</div><div><span style="white-space:pre">			</span>url = url + "/";</div><div><span style="white-space:pre">	</span>}</div><div></div><div><span style="white-space:pre">	</span>@Override</div><div><span style="white-space:pre">	</span>protected void doGet(HttpServletRequest req, HttpServletResponse resp)</div><div><span style="white-space:pre">			</span>throws ServletException, IOException {</div><div><span style="white-space:pre">		</span>this.doPost(req, resp);</div><div><span style="white-space:pre">	</span>}</div><div></div><div><span style="white-space:pre">	</span>@Override</div><div><span style="white-space:pre">	</span>protected void doPost(HttpServletRequest req, HttpServletResponse resp)</div><div><span style="white-space:pre">			</span>throws ServletException, IOException {</div><div><span style="white-space:pre">		</span>String[] target = parse(req.getParameterMap());</div><div><span style="white-space:pre">		</span>process(req, resp, target);</div><div><span style="white-space:pre">	</span>}</div><div>}</div><img src ="http://www.blogjava.net/jjshcc/aggbug/422450.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2015-01-26 17:32 <a href="http://www.blogjava.net/jjshcc/archive/2015/01/26/422450.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中的xml解析时jaxp.properties文件问题</title><link>http://www.blogjava.net/jjshcc/archive/2015/01/15/422236.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Thu, 15 Jan 2015 04:42:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2015/01/15/422236.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/422236.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2015/01/15/422236.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/422236.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/422236.html</trackback:ping><description><![CDATA[<span style="color: #333333; font-size: 13.3333330154419px;">工作中，使用JAVA的JAXP读取解析XML文件中，就碰到了一件奇件的事。在Web工程中，调试发现JAXP实际使用的是Xerces解析器，&nbsp;</span><br style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;" /><span style="color: #333333; font-size: 13.3333330154419px;">可是，当将工程中的一个小Swing工具，与Web使用一样的jar包，打成一个可执行的jar包时，调试却发现JAXP实际使用的是Crimson&nbsp;</span><br style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;" /><span style="color: #333333; font-size: 13.3333330154419px;">解析器，还会发现解析XML文件时出现错误，经过分析，发现Crimson解析器是Sun公司开发的(实际使用发现Crimson没有Xerces解析器稳定)，&nbsp;</span><br style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;" /><span style="color: #333333; font-size: 13.3333330154419px;">打包在JAVA_HOME/lib/dt.jar包中，这个dt.jar被设置在环境变量CLASSPATH中了，当运行可执行的jar包是，JAXP会使用CLASSPATH的解析器，&nbsp;</span><br style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;" /><span style="color: #333333; font-size: 13.3333330154419px;">在Web工程中的War包则不会。&nbsp;</span><br style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;" /><span style="color: #333333; font-size: 13.3333330154419px;">通过阅读JDK源码javax.xml.parsers.FactoryFinder，javax.xml.parsers.SAXParserFactory以及DocumentBuilderFactory发现JDK按照如下顺序：</span><p style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;">1 系统属性javax.xml.parsers.DocumentBuilderFactory或javax.xml.parsers.SAXParserFactory</p><p style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;">2 在jdk-dir/lib/jaxp.properties中设定的javax.xml.parsers.DocumentBuilderFactory或javax.xml.parsers.SAXParserFactory属性</p><p style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;">3 运行时jar包中META-INF/services/javax.xml.parsers.DocumentBuilderFactory或javax.xml.parsers.SAXParserFactory文件中设定的值</p><p style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;">4. 如果上面的解析器都没有找到，则使用Crimson。如果还没有。。。。。。那报ClassNotFound异常了。</p><p style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;">通过JAXP查找解析器的顺序，我们可以使用下面方式来决定，我们使用的实际解析器，<br style="margin: 0px; padding: 0px;" />1 在程序中写死实际的解析器<br style="margin: 0px; padding: 0px;" />如<br style="margin: 0px; padding: 0px;" />javax.xml.parsers.DocumentBuilderFactory factory＝ new org.apache.crimson.jaxp.DocumentBuilderFactoryImpl();<br style="margin: 0px; padding: 0px;" />2 使用JAXP的 DocumentBuilderFactory 工厂类，如<br style="margin: 0px; padding: 0px;" />javax.xml.parsers.DocumentBuilderFactory factory＝ javax.xml.parsers.DocumentBuilderFactory.newInstance();<br style="margin: 0px; padding: 0px;" />再通过下面的方式来指定实际的解析器类<br style="margin: 0px; padding: 0px;" />方法一:在运行java时，通过设置java -D javax.xml.parsers.DocumentBuilderFactory=new org.apache.crimson.jaxp.DocumentBuilderFactoryImpl<br style="margin: 0px; padding: 0px;" />方法二:在程序中调用System.setProperty(&#8220;javax.xml.parsers.DocumentBuilderFactory&#8221;,&#8221; org.apache.crimson.jaxp.DocumentBuilderFactoryImpl&#8221;)<br style="margin: 0px; padding: 0px;" />来设定实际的XML解析器.<br style="margin: 0px; padding: 0px;" />方法三:编写一个jaxp.properties文件，在其中加入如下内容<br style="margin: 0px; padding: 0px;" />javax.xml.parsers.DocumentBuilderFactory=org.apache.crimson.jaxp.DocumentBuilderFactoryImpl<br style="margin: 0px; padding: 0px;" />再将此文件放入JAVA_HOME/lib/下<br style="margin: 0px; padding: 0px;" />方法四:在打jar包下，在目录META-INF/下新建一个services目录，在此目录新建一个文件名为javax.xml.parsers.DocumentBuilderFactory的文件，<br style="margin: 0px; padding: 0px;" />文件内容写上实际使用的解析器类，如写org.apache.crimson.jaxp.DocumentBuilderFactoryImpl<br style="margin: 0px; padding: 0px;" />通过，上面，我们就可以对JAXP有一个比较深的了解。其实，JAVA中有许多这种思想的做法，这种思想，指的是什么的，就是平台无关性，发展到不依赖于具体的实现。<br style="margin: 0px; padding: 0px;" />如我们熟悉的JNDI，JDBC，JAXP等。JNDI是抽像各种目录服务操作的类库，因为目录服务器厂商太多了，如SUN公司的ldapsdk,还有novell公司等等。JDBC是抽像各种数据库<br style="margin: 0px; padding: 0px;" />操作的类库，因为数据库厂商也太多了，如ORACLE，SQLSERVER，MYSQL，INFORMIX等等，JAXP就是抽像各种XML解析器和转换器产品的类库，因为XML解析器和转换器产品够多<br style="margin: 0px; padding: 0px;" />的了。</p><p style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;"><span style="margin: 0px; padding: 0px; font-family: 宋体; font-size: 10pt;"><span style="margin: 0px; padding: 0px; font-size: 10pt;"><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px;">访问</span>AIX<span style="margin: 0px; padding: 0px;">系统中部署在</span>OC4J<span style="margin: 0px; padding: 0px;">中的</span>web</span>&nbsp;</span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-size: 10pt;"><span style="margin: 0px; padding: 0px;">模块的页面时遇到这个错误：<br style="margin: 0px; padding: 0px;" />javax.xml.parsers.FactoryConfigurationError: Provider null could not be instantiated:&nbsp;<br style="margin: 0px; padding: 0px;" />java.lang.NullPointerException<br style="margin: 0px; padding: 0px;" /></span></span><span style="margin: 0px; padding: 0px; font-family: 'Times New Roman'; font-size: 10.5pt;"><span style="margin: 0px; padding: 0px; font-size: 10pt;">at javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source)<br style="margin: 0px; padding: 0px;" />at org.apache.commons.digester.Digester.getFactory(Digester.java:478)<br style="margin: 0px; padding: 0px;" />at org.apache.commons.digester.Digester.getParser(Digester.java:683)<br style="margin: 0px; padding: 0px;" />at org.apache.commons.digester.Digester.getXMLReader(Digester.java:891)<br style="margin: 0px; padding: 0px;" />at org.apache.commons.digester.Digester.parse(Digester.java:1591)<br style="margin: 0px; padding: 0px;" />at org.apache.struts.action.ActionServlet.initServlet(ActionServlet.java:1433)<br style="margin: 0px; padding: 0px;" />at org.apache.struts.action.ActionServlet.init(ActionServlet.java:466)<br style="margin: 0px; padding: 0px;" />at javax.servlet.GenericServlet.init(GenericServlet.java:256)<br style="margin: 0px; padding: 0px;" />at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) ].server.http.HttpApplication.loadServlet(HttpApplication.java:2231)<br style="margin: 0px; padding: 0px;" />at com.evermind[Oracle Containers for J2EE 10g (10.1.3.0.0) ].server.http.HttpApplication.findServlet(HttpApplication.java:4617)<br style="margin: 0px; padding: 0px;" />&#8230;&#8230;<br style="margin: 0px; padding: 0px;" /></span><span style="margin: 0px; padding: 0px; font-family: 宋体; font-size: 10pt;"><span style="margin: 0px; padding: 0px; font-size: 10pt;"><span style="margin: 0px; padding: 0px;">或者这样的异常：<br style="margin: 0px; padding: 0px;" /></span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px;">javax.servlet.jsp.JspException: Can't get definitions factory from context.<br style="margin: 0px; padding: 0px;" />at org.apache.struts.taglib.tiles.InsertTag.processDefinitionName(InsertTag.java:583)<br style="margin: 0px; padding: 0px;" />at org.apache.struts.taglib.tiles.InsertTag.createTagHandler(InsertTag.java:487)<br style="margin: 0px; padding: 0px;" />at org.apache.struts.taglib.tiles.InsertTag.doStartTag(InsertTag.java:451)<br style="margin: 0px; padding: 0px;" />at _welcome._jspService(_welcome.java:54)<br style="margin: 0px; padding: 0px;" />[SRC:/welcome.jsp:4]</span></span></span></span></span></span></span></p><p style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;"><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-size: 10pt;"><span style="margin: 0px; padding: 0px; font-family: 宋体;">&#8230;&#8230;</span>&nbsp;<br style="margin: 0px; padding: 0px;" /></span><span style="margin: 0px; padding: 0px; font-size: 10pt;"><span style="margin: 0px; padding: 0px; font-family: 宋体; font-size: 10.5pt;"><span style="margin: 0px; padding: 0px; font-size: 10pt;"><span style="margin: 0px; padding: 0px;">而当在<span style="margin: 0px; padding: 0px; font-family: 'Times New Roman';">Windows</span><span style="margin: 0px; padding: 0px;">环境下部署时就没有问题。</span></span></span></span></span></span></p><p style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;"><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-size: 10pt;"><span style="margin: 0px; padding: 0px; font-family: 宋体;">这里是因为</span>IBM<span style="margin: 0px; padding: 0px; font-family: 宋体;">的</span>AIX<span style="margin: 0px; padding: 0px; font-family: 宋体;">系统使用的是</span>IBM<span style="margin: 0px; padding: 0px; font-family: 宋体;">的</span>JDK<span style="margin: 0px; padding: 0px; font-family: 宋体;">。而</span><span style="margin: 0px; padding: 0px; font-family: 宋体;">出现这个问题正是因为</span>IBM<span style="margin: 0px; padding: 0px; font-family: 宋体;">和</span>SUN<span style="margin: 0px; padding: 0px; font-family: 宋体;">的</span>JDK<span style="margin: 0px; padding: 0px; font-family: 宋体;">的差异。</span></span>&nbsp;<span style="margin: 0px; padding: 0px; font-size: 10pt;"><span style="margin: 0px; padding: 0px; font-family: 宋体;">具体是因为</span>$JAVA_HOME/jre/lib/jaxp.properties&nbsp;<span style="margin: 0px; padding: 0px; font-family: 宋体;">这个文件。</span></span></span></p><p style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;"><span style="margin: 0px; padding: 0px; font-size: 10pt;"><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 宋体;">这个文件以</span>key=value<span style="margin: 0px; padding: 0px; font-family: 宋体;">的形式配置和指定实际使用的</span>XML<span style="margin: 0px; padding: 0px; font-family: 宋体;">解析器实现类</span>(<span style="margin: 0px; padding: 0px; font-family: 宋体;">譬如：</span>javax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl)<span style="margin: 0px; padding: 0px; font-family: 宋体;">。在</span>XML<span style="margin: 0px; padding: 0px; font-family: 宋体;">解析器初始化之前，</span>JDK<span style="margin: 0px; padding: 0px; font-family: 宋体;">首先会搜索</span>System<span style="margin: 0px; padding: 0px; font-family: 宋体;">的</span>properties<span style="margin: 0px; padding: 0px; font-family: 宋体;">寻找解析器的配置项，如果没有则会搜索</span>&nbsp;$JAVA_HOME/jre/lib&nbsp;<span style="margin: 0px; padding: 0px; font-family: 宋体;">路径下的</span>&nbsp;jaxp.properties&nbsp;<span style="margin: 0px; padding: 0px; font-family: 宋体;">文件，如果还没有，接下来会在</span>classpath<span style="margin: 0px; padding: 0px; font-family: 宋体;">上的</span>.jar<span style="margin: 0px; padding: 0px; font-family: 宋体;">包中寻找，仍然没有的话就会使用默认的解析器。</span></span></span></p><p style="margin: 0px; padding: 0px; color: #333333; font-size: 13.3333330154419px;"><span style="margin: 0px; padding: 0px; font-size: 10pt;"><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 宋体;">实际上这个文件在</span>SUN<span style="margin: 0px; padding: 0px; font-family: 宋体;">的</span>JDK<span style="margin: 0px; padding: 0px; font-family: 宋体;">中是不存在的。在找不到文件的情况下，最终将使用默认解析器。在</span>IBM<span style="margin: 0px; padding: 0px; font-family: 宋体;">的</span>JDK<span style="margin: 0px; padding: 0px; font-family: 宋体;">中存在</span>&nbsp;jaxp.properties<span style="margin: 0px; padding: 0px; font-family: 宋体;">这个文件。但是这个文件中默认所有的配置项是注释掉的，所以在搜索到此处时，不再继续向下搜索，但是由于读取不到配置项，所以会返回</span>null&nbsp;<span style="margin: 0px; padding: 0px; font-family: 宋体;">，于是出现了上文的第一个错误。第二个异常大概是因为访问使用</span>tiles<span style="margin: 0px; padding: 0px; font-family: 宋体;">框架的页面时，由于</span>XML<span style="margin: 0px; padding: 0px; font-family: 宋体;">解析器初始化出错，所以</span>tiles<span style="margin: 0px; padding: 0px; font-family: 宋体;">框架的配置文件也就读取不了了。</span></span></span></p><img src ="http://www.blogjava.net/jjshcc/aggbug/422236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2015-01-15 12:42 <a href="http://www.blogjava.net/jjshcc/archive/2015/01/15/422236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java /Jsp 执行操作系统命令 windows/Linux </title><link>http://www.blogjava.net/jjshcc/archive/2014/12/24/421746.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Wed, 24 Dec 2014 04:01:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/12/24/421746.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/421746.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/12/24/421746.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/421746.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/421746.html</trackback:ping><description><![CDATA[<div id="article_content"> <p>1.Windows 很简单，写出来时为了和linux对比</p> <p>&nbsp;&nbsp; public void execWindowsCmd(String cmd) throws Exception {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Runtime  rt = Runtime.getRuntime();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Process ppp = rt.exec(cmd);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //input<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStreamReader ir = new  InputStreamReader(ppp.getInputStream());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LineNumberReader input = new  LineNumberReader(ir);</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String line;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((line = input.readLine()) !=  null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; com.pub.Log.logger.debug(this.getClass().getClass() + " "  +<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line);</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //error<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ir = new  InputStreamReader(ppp.getErrorStream());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; input = new  LineNumberReader(ir);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((line = input.readLine()) !=  null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; com.pub.Log.logger.debug(this.getClass().getClass() + " "  +<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line);</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ppp.waitFor();<br />&nbsp;&nbsp; }</p> <p>&nbsp;</p> <p>2. Linux  ：首先要确保对于命令，允许Web服务器的用户是否有权限，普通命令和windows没什么区别。Linux管道命令不能这样直接执行，下面是具体实现fang</p> <p>&nbsp;&nbsp; public void execLinuxCmd(String cmd) throws Exception {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Runtime  rt = Runtime.getRuntime();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File f = new File(this.fileName +  PDU_SHELL);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BufferedWriter bw = new BufferedWriter(new  FileWriter(f));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bw.write("#!/bin/bash");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  bw.newLine();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bw.write(cmd);&nbsp; //把命令写入一个文本shell文件<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  bw.flush();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bw.close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd = f.getAbsolutePath();</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Process ppp = rt.exec("chmod a+x " + cmd);&nbsp;&nbsp;//授权该shell文件可以执行<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  ppp.waitFor();</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ppp = rt.exec(cmd);&nbsp; //执行shell</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //input<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStreamReader ir = new  InputStreamReader(ppp.getInputStream());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LineNumberReader input = new  LineNumberReader(ir);</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String line;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((line = input.readLine()) !=  null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; com.pub.Log.logger.debug(this.getClass().getClass() + " "  +<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line);</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //error<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ir = new  InputStreamReader(ppp.getErrorStream());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; input = new  LineNumberReader(ir);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((line = input.readLine()) !=  null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; com.pub.Log.logger.debug(this.getClass().getClass() + " "  +<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; line);</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ppp.waitFor();</p> <p>&nbsp;&nbsp; }</p></div><img src ="http://www.blogjava.net/jjshcc/aggbug/421746.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-12-24 12:01 <a href="http://www.blogjava.net/jjshcc/archive/2014/12/24/421746.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>10个基于Java的CMS网站内容管理系统</title><link>http://www.blogjava.net/jjshcc/archive/2014/11/11/419927.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Tue, 11 Nov 2014 07:50:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/11/11/419927.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/419927.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/11/11/419927.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/419927.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/419927.html</trackback:ping><description><![CDATA[<div>在 开始研究 java CMS之前，我们先要了解什么是CMS。CMS &#8212; Content Management  Systems，内容管理系统，简单的说，就是一个帮助进行网站内容管理的系统。CMS通常包含两部分：内容管理程序(Content  Management Application ,CMA)和内容发布程序(Content Delivery Application  ,CDA)，内容管理程序可以帮助网站管理员轻松的实现网站文章的创建、编辑和删除操作，内容发布程序则可以编辑文章并在网站上发布它们。<div><a><img style="max-width:300px;" id="img3" src="http://image51.360doc.cn/DownloadImg/2012/04/1809/23286270_4.jpg"  alt="" /></a></div>一 个完整的CMS通常包含一个在线的发布、排版、版本控制，以及列表、搜索、恢复等功能模块。近年来大量涌现的企业网站管理系统，则增加了新闻管  理、使用手册、在线帮助、销售手册等功能。难以避免的，功能强大的CMS往往有着高昂的售价，预算不足的用户很希望找到一款好用且免费的管理系统。现在已  经出现了许多基于java的开源CMS系统，本文挑选了10个最强大、最易用的CMS，向大家做一个简要介绍。1. Alfresco<div><a><img style="max-width:300px;" id="img4" src="http://image51.360doc.cn/DownloadImg/2012/04/1809/23286270_5.png"  alt="" /></a></div>Alfresco是一个开源的企业网站内容管理系统，它提供了文档管理、多人协作、记录管理、知识管理网页内容和图像管理等功能。它使用Spring、 Hibernate、 Lucene 和JSF等最新java技术构建了模块化的系统架构。Alfresco官方网站:http://www.alfresco.com/中文教程:http://blog.csdn.net/alfresco/2. DotCMS<div><a><img style="max-width:300px;" id="img5" src="http://image51.360doc.cn/DownloadImg/2012/04/1809/23286270_6.jpg"  alt="" /></a></div>DotCMS 是一个开源的企业级内容管理系统，它融入了电子商  务、个性化设置、客户关系管理工具等功能，它可以方便的建立基于各种关系的数据结构和数据库，它可以使用模板快速创建页面，并且提供了一个强大的所见即所  得(WYSIWYG)编辑器。用户可以使用加载外部模块的功能快速的建立Ajax应用、搜索、MP3播放器、幻灯片和相册等功能。DotCMS官方网站http://dotcms.org/中文安装教程http://www.javaeye.com/wiki/topic/2777943. Magnolia<div><a><img style="max-width:300px;" id="img6" src="http://image51.360doc.cn/DownloadImg/2012/04/1809/23286270_7.png"  alt="" /></a></div>Magnolia 是一个老牌的java内容管理系统，目前已经发布了第四版。它的独特之处在于可以定制内容模型，以返回数组形式来搞定各种不确定的  功能。它遵循W3C标准并且在搜索引擎优化上有许多优势。同时它支持java内容仓库( java content repositories ,  JCR) 的API。Magnolia官方网站http://www.magnolia-cms.com/home.html4. OpenCms<div><a><img style="max-width:300px;" id="img7" src="http://image51.360doc.cn/DownloadImg/2012/04/1809/23286270_8.gif"  alt="" /></a></div>它提供了一套建立和维护网站的方便的工具。在内容建设方面，它拥有一个易于使用的界面和所见即所得编辑器，在网页生成上它使用了一个先进的页面模板。OpenCMS官方网站http://www.opencms.org/opencms/en/index.html中文网站http://www.opencms.cn/6. AtLeap<div><a><img style="max-width:300px;" id="img8" src="http://image51.360doc.cn/DownloadImg/2012/04/1809/23286270_9.gif"  alt="" /></a></div>Blandware AtLeap是一个多语种的免费Java内容管理系统，它包含了全文搜索引擎，可以算是一个能让你方便的编写应用的网站框架。Atleap官方网站https://atleap.dev.java.net/7. Fedora<div><a><img style="max-width:300px;" id="img9" src="http://image51.360doc.cn/DownloadImg/2012/04/1809/23286270_10.jpg"  alt="" /></a></div>Fedora 是&#8220;Flexible Extensible Digital Object Repository  Architecture&#8221;的缩写，并不是Linux发行版Fedora，是一个数字资源管理系统，它可以创建很多类型的数字图书馆、资料库、档案馆系统  等。Fedora官方网站http://www.fedora-commons.org/8. Apache Lenya<div><a><img style="max-width:300px;" id="img10" src="http://image51.360doc.cn/DownloadImg/2012/04/1809/23286270_11.gif"  alt="" /></a></div>这是一个开源的 Java/XML 内容管理系统，提供了版本控制、多站点管理、调度、搜索、所见即所得编辑以及工作流程等功能。Apache Lyenya使用基于模块的Cocoom开源程序框架。Apache Lyenya官方网站http://lenya.apache.org/9. OpenEdit<div><a><img style="max-width:300px;" id="img11" src="http://image51.360doc.cn/DownloadImg/2012/04/1809/23286270_12.jpg"  alt="" /></a></div>OpenEdit是一个开源的内容管理系统，它旨在建设基于在线数字资产的多媒体网站。它提供在线编辑，动态布局，拼写检查，用户管理器，文件管理器，版本控制和通知工具。同时包含企业级的插件，如电子商务，内容管理，博客，活动日程表，社交网络工具等。OpenEdit官方网站http://www.openedit.org/10.&nbsp; Contelligent这个基于Java的开源解决方案有助于创建和管理个性化网站。它完全遵循J2EE，具有先进的模式，可以方便的添加第三方应用。Contelligent官方网站http://www.contelligent.com/           </div><img src ="http://www.blogjava.net/jjshcc/aggbug/419927.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-11-11 15:50 <a href="http://www.blogjava.net/jjshcc/archive/2014/11/11/419927.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java读取properties配置文件时，中文乱码解决方法 .</title><link>http://www.blogjava.net/jjshcc/archive/2014/10/10/418571.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Fri, 10 Oct 2014 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/10/10/418571.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/418571.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/10/10/418571.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/418571.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/418571.html</trackback:ping><description><![CDATA[<p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">碰到了用java.util.Properties读取中文内容（UTF-8格式）的配置文件，发生中文乱码的现象，</p>
<p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">&nbsp;</p>
<div style="padding-bottom: 1px; overflow-x: auto; overflow-y: auto; background-color: transparent; padding-left: 1px; width: 679px; padding-right: 1px; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; word-wrap: break-word; margin-left: 9px; font-size: 12px; word-break: break-all; padding-top: 1px" class="dp-highlighter">
<div class="bar">
<div style="text-align: left; padding-bottom: 3px; margin: 0px; padding-left: 3px; padding-right: 3px; color: black; font-weight: bold; padding-top: 3px" class="tools">Java代码&nbsp;&nbsp;<a style="color: rgb(16,138,198); text-decoration: underline" title="收藏这段代码" href="http://pig345.iteye.com/blog/725974"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="star" alt="收藏代码" src="http://pig345.iteye.com/images/icon_star.png" /></a></div></div>
<ol style="border-bottom: rgb(209,215,220) 1px solid; border-left: rgb(209,215,220) 1px solid; padding-bottom: 2px; line-height: 1.4em; background-color: rgb(255,255,255); list-style-type: decimal; margin: 0px 0px 1px; padding-left: 0px; padding-right: 0px; color: rgb(43,145,175); font-size: 1em; border-top: rgb(209,215,220) 1px solid; border-right: rgb(209,215,220) 1px solid; padding-top: 2px" class="dp-j"><li style="border-left: rgb(209,215,220) 1px solid; padding-bottom: 0px; line-height: 18px; background-color: rgb(250,250,250); margin: 0px 0px 0px 38px; padding-left: 10px; padding-right: 0px; font-size: 1em; padding-top: 0px"><span style="color: black"><span style="color: black">Properties&nbsp;prop=</span><span style="color: rgb(127,0,85); font-weight: bold" class="keyword">new</span><span style="color: black">&nbsp;Properties();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li style="border-left: rgb(209,215,220) 1px solid; padding-bottom: 0px; line-height: 18px; background-color: rgb(250,250,250); margin: 0px 0px 0px 38px; padding-left: 10px; padding-right: 0px; font-size: 1em; padding-top: 0px"><span style="color: black">prop.load(Client.<span style="color: rgb(127,0,85); font-weight: bold" class="keyword">class</span><span style="color: black">.getClassLoader().getResourceAsStream(</span><span style="color: blue" class="string">"config.properties"</span><span style="color: black">));&nbsp;&nbsp;</span></span></li></ol></div>
<p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">&nbsp;</p>
<p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">习惯性google了一下，网上大多数文章都是让大家用<span style="color: rgb(0,0,0)">native2ascii.exe转换</span>&nbsp;这样的解决方案，一开始还差点被懵住了，以为只能使用这样的绕弯子方法。。。</p>
<p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">&nbsp;</p>
<p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">但关键是，<span style="color: rgb(0,0,0)">太绕了！</span>&nbsp;如果每次都用native2ascii.exe将中文转换成\uXXXX\uXXXX这样的，麻烦先不说，转换完后的文件完全不可读！！！这基本上是不可忍受的！<br />（虽然也能用native2ascii.exe转换回来，但同样，麻烦！）<br /><br />冷静下来后，突然想起来，还是初学java时看过，java.io包中 Reader/Writer和Stream的区别。<br />（年代久远，具体细节忘记了，大概是：<span style="color: rgb(255,0,0)">Reader/Write是处理编码文本的，而InputStream/OutputStream只把数据当作2进制流</span>&nbsp;）<br /><br />正确解决方案</p>
<p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">&nbsp;</p>
<div style="padding-bottom: 1px; overflow-x: auto; overflow-y: auto; background-color: transparent; padding-left: 1px; width: 679px; padding-right: 1px; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; word-wrap: break-word; margin-left: 9px; font-size: 12px; word-break: break-all; padding-top: 1px" class="dp-highlighter">
<div class="bar">
<div style="text-align: left; padding-bottom: 3px; margin: 0px; padding-left: 3px; padding-right: 3px; color: black; font-weight: bold; padding-top: 3px" class="tools">Java代码&nbsp;&nbsp;<a style="color: rgb(16,138,198); text-decoration: underline" title="收藏这段代码" href="http://pig345.iteye.com/blog/725974"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" class="star" alt="收藏代码" src="http://pig345.iteye.com/images/icon_star.png" /></a></div></div>
<ol style="border-bottom: rgb(209,215,220) 1px solid; border-left: rgb(209,215,220) 1px solid; padding-bottom: 2px; line-height: 1.4em; background-color: rgb(255,255,255); list-style-type: decimal; margin: 0px 0px 1px; padding-left: 0px; padding-right: 0px; color: rgb(43,145,175); font-size: 1em; border-top: rgb(209,215,220) 1px solid; border-right: rgb(209,215,220) 1px solid; padding-top: 2px" class="dp-j"><li style="border-left: rgb(209,215,220) 1px solid; padding-bottom: 0px; line-height: 18px; background-color: rgb(250,250,250); margin: 0px 0px 0px 38px; padding-left: 10px; padding-right: 0px; font-size: 1em; padding-top: 0px"><span style="color: black"><span style="color: black">Properties&nbsp;prop=</span><span style="color: rgb(127,0,85); font-weight: bold" class="keyword">new</span><span style="color: black">&nbsp;Properties();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li style="border-left: rgb(209,215,220) 1px solid; padding-bottom: 0px; line-height: 18px; background-color: rgb(250,250,250); margin: 0px 0px 0px 38px; padding-left: 10px; padding-right: 0px; font-size: 1em; padding-top: 0px"><span style="color: black">prop.load(<span style="color: rgb(127,0,85); font-weight: bold" class="keyword">new</span><span style="color: black">&nbsp;InputStreamReader(Client.</span><span style="color: rgb(127,0,85); font-weight: bold" class="keyword">class</span><span style="color: black">.getClassLoader().getResourceAsStream(</span><span style="color: blue" class="string">"config.properties"</span><span style="color: black">),&nbsp;</span><span style="color: blue" class="string">"UTF-8"</span><span style="color: black">));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li></ol></div>
<p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">&nbsp;</p>
<p style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">其中&#8220;UTF-8&#8221;，用于明确指定.properties文件的编码格式（不指定则默认使用OS的，这会造成同一份配置文件同一份代码，在linux和windows上、英文windows和中文windows之间的表现都不一致），这个参数应该和具体读取的properties文件的格式匹配。&nbsp;</p><br /><img src ="http://www.blogjava.net/jjshcc/aggbug/418571.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-10-10 09:39 <a href="http://www.blogjava.net/jjshcc/archive/2014/10/10/418571.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>httpclient 实现自动登录NTLM 域验证（sso） .</title><link>http://www.blogjava.net/jjshcc/archive/2014/10/09/418547.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Thu, 09 Oct 2014 03:53:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/10/09/418547.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/418547.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/10/09/418547.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/418547.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/418547.html</trackback:ping><description><![CDATA[<div><font face="Simsun">最近一个项目拿到客户那运行不了</font><span style="line-height: 25px; font-family: 宋体"><span style="font-size: 12px">。<span style="line-height: 25px; font-family: 宋体; font-size: 14px">原来我的</span></span></span><span style="line-height: 25px; font-family: 宋体; font-size: 14px">这个项目要和另一个系统通过http的接口进行通讯。但在客户的生产环境中，那套系统将web应用的登录和<span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px">Windows Domain的登录结合，做了一个sso单点登录（jcifs实现）。那么我必须要修改我的程序，好自动登录<span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px">Windows Domain。</span></span></span> 
<p><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px">&nbsp; 通过抓包分析，局域网使用的是<strong style="background-color: #ffff66; color: black">NTLM</strong> 协议。</span></span></span></p>
<p><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="font-family: 宋体">&nbsp;当通过浏览器访问被<span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><strong style="background-color: #ffff66; color: black">NTLM</strong>协议</span>保护的资源的时候，<span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><strong style="background-color: #ffff66; color: black">NTLM</strong><span style="font-family: 宋体">的认证方式和流程如下：</span></span><span style="font-family: Simsun; font-size: 16px"></span></span></span></span></span></span></p><pre>    1: C  --&gt; S   GET ...
    
    2: C &lt;--  S   401 Unauthorized
                  WWW-Authenticate: <strong style="background-color: #ffff66; color: black">NTLM</strong>
    
    3: C  --&gt; S   GET ...
                  Authorization: <strong style="background-color: #ffff66; color: black">NTLM</strong> &lt;base64-encoded type-1-message&gt;
    
    4: C &lt;--  S   401 Unauthorized
                  WWW-Authenticate: <strong style="background-color: #ffff66; color: black">NTLM</strong> &lt;base64-encoded type-2-message&gt;
    
    5: C  --&gt; S   GET ...
                  Authorization: <strong style="background-color: #ffff66; color: black">NTLM</strong> &lt;base64-encoded type-3-message&gt;
    
    6: C &lt;--  S   200 Ok</pre>
<p>&nbsp;</p>
<p><span style="line-height: 25px; font-size: 14px"><span style="line-height: 25px; font-size: 14px"><span style="line-height: 25px; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"></span></span></span></span></p>
<p style="margin: 5px auto; font-family: verdana, Arial, Helvetica; font-size: 14px">Type-1<span style="font-family: 宋体">消息包括机器名、</span>Domain<span style="font-family: 宋体">等</span></p>
<p style="margin: 5px auto; font-family: verdana, Arial, Helvetica; font-size: 14px">Type-2<span style="font-family: 宋体">消息包括</span>server<span style="font-family: 宋体">发出的</span><strong style="background-color: #ffff66; color: black">NTLM</strong> challenge</p>
<p style="margin: 5px auto; font-family: verdana, Arial, Helvetica; font-size: 14px">Type-3<span style="font-family: 宋体">消息包括用户名、机器名、</span>Domain<span style="font-family: 宋体">、以及两个根据</span>server<span style="font-family: 宋体">发出的</span>challenge<span style="font-family: 宋体">计算出的</span>response<span style="font-family: 宋体">，这里</span>response<span style="font-family: 宋体">是基于</span>challenge<span style="font-family: 宋体">和当前用户的登录密码计算而得</span></p><span style="font-family: verdana, Arial, Helvetica">PS：在第二步时，当浏览器接收到一个401 Unauthorized&nbsp;</span><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="font-family: 宋体">的</span>response</span><span style="line-height: 25px; font-size: 14px"><span style="font-family: 宋体">，会<span style="line-height: 25px; font-family: 宋体; font-size: 14px">弹出该对话框让用户输入用户名、密码。（ie有可能会自动登录）</span></span></span><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"></span></span></span> 
<p><span style="line-height: 25px; font-size: 14px"><span style="line-height: 25px; font-size: 14px"><span style="line-height: 25px; font-size: 14px"><span style="line-height: 25px; font-size: 14px"><span style="font-family: 宋体"><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><img alt="" src="http://my.csdn.net/uploads/201204/10/1334041246_3214.jpg" /><br /></span></span></span></span></span></span></p>
<p><span style="line-height: 25px; font-size: 14px"><span style="line-height: 25px; font-size: 14px"><span style="line-height: 25px; font-size: 14px"><span style="line-height: 25px; font-size: 14px"><span style="font-family: 宋体"><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><br /></span></span></span></span></span></span></p>
<p><span style="font-family: 宋体"><span style="line-height: 25px; font-size: 14px">我的程序（client）要和另个程序走http接口通讯（server），<span style="line-height: 25px; font-family: 宋体; font-size: 14px">server再去ad验证域登录</span></span></span></p>
<p><span style="font-family: 宋体"><span style="line-height: 25px; font-size: 14px"><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><br /></span></span></span></p>
<p><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><img alt="" src="http://my.csdn.net/uploads/201204/10/1334042084_5770.jpg" /></span></span></span></span></span></p>
<p><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><br /></span></span></span></span></span></p>
<p><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica; font-size: 14px"><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><strong style="background-color: #a0ffff; color: black">httpclient</strong> 实现<strong style="background-color: #ffff66; color: black">NTLM</strong>验证（当然你也可以自己实现协议）</span></span></span></span></span></p>
<p><span style="line-height: 25px; font-family: 宋体"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica"><span style="line-height: 25px; font-family: 宋体"><span style="line-height: 16px; font-family: Verdana, Helvetica, Arial, sans-serif"><span style="font-size: 12px"><strong style="background-color: #a0ffff; color: black">HttpClient</strong>从version 4.1 <span style="line-height: 25px; font-family: 宋体; font-size: 14px">开始<span style="line-height: 25px; font-family: 宋体; font-size: 14px">完全支持</span></span><strong style="background-color: #ffff66; color: black">NTLM</strong> authentication protocol（NTLMv1, NTLMv2, &nbsp;and <strong style="background-color: #ffff66; color: black">NTLM</strong>2 &nbsp;），<span style="line-height: 25px; font-family: 宋体; font-size: 14px">文档的原话是&#8220;The <strong style="background-color: #ffff66; color: black">NTLM</strong> authentication scheme is significantly more expensive in terms of computational overhead<br />and performance &nbsp;impact &nbsp;than &nbsp;the &nbsp;standard Basic &nbsp;and Digest &nbsp;schemes.&#8221;</span></span></span><br /></span></span></span></span></span></p>
<p><span style="line-height: 25px; font-family: 宋体"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica"><span style="line-height: 25px; font-family: 宋体"><span style="line-height: 16px; font-family: Verdana, Helvetica, Arial, sans-serif"><span style="font-size: 12px"><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><span style="line-height: 25px; font-family: 宋体; font-size: 14px">但是使用起来还是非常的方便的。因为 <strong style="background-color: #ffff66; color: black">NTLM</strong> 连接是有状态的，通常建议使用相对简单的方法触发<strong style="background-color: #ffff66; color: black">NTLM</strong> 认证，比如GET或 HEAD， 而重用相同的连接来执行代价更大的方法，特别是它们包含请求实体，比如 POST或 PUT。</span></span></span></span></span></span></span></span></span></p>
<p><span style="line-height: 25px; font-family: 宋体"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica"><span style="line-height: 25px; font-family: verdana, Arial, Helvetica"><span style="line-height: 25px; font-family: 宋体"><span style="line-height: 16px; font-family: Verdana, Helvetica, Arial, sans-serif"><span style="font-size: 12px"><span style="line-height: 25px; font-family: 宋体; font-size: 14px"><span style="line-height: 25px; font-family: 宋体; font-size: 14px"></span></span></span></span></span></span></span></span></span></p><pre class="java" name="code">DefaultHttpClient <strong style="background-color: #a0ffff; color: black">httpclient</strong> = new DefaultHttpClient(); 
NTCredentials creds = new NTCredentials("user", "pwd", 
"myworkstation", "microsoft.com"); 
<strong style="background-color: #a0ffff; color: black">httpclient</strong>.getCredentialsProvider().setCredentials(AuthScop
.ANY, creds); 
HttpHost target = new HttpHost("www.microsoft.com", 80, 
"http"); 
// 保证相同的内容来用于执行逻辑相关的请求 
HttpContext localContext = new BasicHttpContext(); 
// 首先执行简便的方法。这会触发<strong style="background-color: #ffff66; color: black">NTLM</strong>认证 
HttpGet httpget = new HttpGet("/<strong style="background-color: #ffff66; color: black">ntlm</strong>-protected/info"); 
HttpResponse response1 = <strong style="background-color: #a0ffff; color: black">httpclient</strong>.execute(target, httpget
localContext); 
HttpEntity entity1 = response1.getEntity(); 
if (entity1 != null) { 
entity1.consumeContent(); 
} 
//之后使用相同的内容（和连接）执行开销大的方法。 
HttpPost httppost = new HttpPost("/<strong style="background-color: #ffff66; color: black">ntlm</strong>-protected/form"); 
httppost.setEntity(new StringEntity("lots and lots of data"))
HttpResponse response2 = <strong style="background-color: #a0ffff; color: black">httpclient</strong>.execute(target, httppost,
localContext); 
HttpEntity entity2 = response2.getEntity(); 
if (entity2 != null) { 
entity2.consumeContent(); 
} </pre><br /><br /><br /><br />import org.apache.commons.httpclient.ProxyHost;<br />import org.apache.http.HttpEntity;<br />import org.apache.http.HttpHost;<br />import org.apache.http.HttpResponse;<br />import org.apache.http.ParseException;<br />import org.apache.http.auth.AuthScope;<br />import org.apache.http.auth.UsernamePasswordCredentials;<br />import org.apache.http.client.ClientProtocolException;<br />import org.apache.http.client.HttpClient;<br />import org.apache.http.client.methods.HttpGet;<br />import org.apache.http.conn.params.ConnRouteParams;<br />import org.apache.http.impl.client.DefaultHttpClient;<br />import org.apache.http.util.EntityUtils;</div><br /><br />
<div>&nbsp;&nbsp; &nbsp;&nbsp; private HttpClient getHttpClient() {<br /><br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;DefaultHttpClient httpClient = new DefaultHttpClient();<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String proxyHost = "";<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;int proxyPort = 8080;<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String userName = "";<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;String password = "";<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;httpClient.getCredentialsProvider().setCredentials(<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;new AuthScope(proxyHost, proxyPort),<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;new UsernamePasswordCredentials(userName, password));<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;HttpHost proxy = new HttpHost(proxyHost, proxyPort);<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY,<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;proxy);<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return httpClient;<br />&nbsp;&nbsp; &nbsp;}</div><img src ="http://www.blogjava.net/jjshcc/aggbug/418547.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-10-09 11:53 <a href="http://www.blogjava.net/jjshcc/archive/2014/10/09/418547.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SSL-用Keytool和OpenSSL生成和签发数字证书</title><link>http://www.blogjava.net/jjshcc/archive/2014/07/22/416086.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Tue, 22 Jul 2014 06:42:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/07/22/416086.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/416086.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/07/22/416086.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/416086.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/416086.html</trackback:ping><description><![CDATA[<div><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 21pt; ">J2SDK在目录%JAVA_HOME%/bin提供了密钥库管理工具Keytool，用于管理密钥、证书和证书链。Keytool工具的命令在JavaSE6中已经改变，不过以前的命令仍然支持。Keytool也可以用来管理对称加密算法中的密钥。</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 21pt; ">最简单的命令是生成一个自签名的证书，并把它放到指定的keystore文件中：</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 31.5pt; ">keytool -genkey -alias tomcat -keyalg RSA -keystore c:/mykey</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; text-indent: 21.75pt; ">如果c:/mykey文件不存在，<span>keytool会生成这个文件。按照命令的提示，回答一系列问题，就生成了数字证书。注意，公共名称(cn)应该是服务器的域名。这样keystore中就存在一个别名为tomcat的实体，它包括公钥、私钥和证书。这个证书是自签名的。&nbsp;</span></p>Keytool工具可以从keystore中导出证书，但是不能导出私钥。对于配置<span>apache这样的服务器，就不太方便。这种情况下就完全用OpenSSL吧，上一篇文章《</span>SSL-用OpenSSL生成证书文件》中已经做了介绍。不过keytool对于J2EE　AppServer是很有用的，它们就是用keystore存储证书链的。keystore的作用类似于windows存放证书的方式，不过跨平台了，^_^下面用Keytool生成CSR（Certificate Signing Request），并用OpenSSL生成CA签名的证书。<br /><br />1.&nbsp;&nbsp;&nbsp; 准备<br />1)&nbsp;&nbsp;&nbsp; 在bin目录下新建目录 demoCA、demoCA/certs、demoCA/certs&nbsp; 、 demoCA/newcerts<br />2)&nbsp;&nbsp;&nbsp; 在demoCA建立一个空文件 index.txt<br />3)&nbsp;&nbsp;&nbsp; 在demoCA建立一个文本文件 serial, 没有扩展名，内容是一个合法的16进制数字，例如 0000<br />4)&nbsp;&nbsp;&nbsp; 配置环境变量PATH，加入%JAVA_HOME%/bin，本文用的JavaSDK1.6<br /><br />2.&nbsp;&nbsp;&nbsp; 生成CA的自签名证书<br />openssl req -new -x509 -keyout ca.key -out ca.crt -config openssl.cnf<br /><br />3.&nbsp;&nbsp;&nbsp; 生成server端证书<br />1)&nbsp;&nbsp;&nbsp; 生成KeyPair生成密钥对<br />&nbsp;keytool -genkey -alias tomcat_server -validity 365 -keyalg RSA -keysize 1024 -keypass 123456&nbsp; -storepass 123456 -keystore server_keystore<br />&nbsp; 输入common name时，要和服务器的域名保持一致。<br />2)&nbsp;&nbsp;&nbsp; 生成证书签名请求<br />keytool -certreq -alias tomcat_server -sigalg MD5withRSA -file tomcat_server.csr -keypass 123456 -storepass 123456 -keystore server_keystore&nbsp;<br />3)&nbsp;&nbsp;&nbsp; 用CA私钥进行签名，也可以到权威机构申请CA签名。<br />&nbsp;&nbsp; openssl ca -in tomcat_server.csr -out tomcat_server.crt -cert ca.crt -keyfile ca.key -notext -config openssl.cnf<br />&nbsp; 其中-notext表示不要把证书文件的明文内容输出到文件中去，否则在后面用keytool导入到keystore时会出错。<br />4)&nbsp;&nbsp;&nbsp; 导入信任的CA根证书到keystore<br />&nbsp;&nbsp; keytool -import -v -trustcacerts&nbsp; -alias my_ca_root -file ca.crt -storepass 123456 -keystore server_keystore<br />5)&nbsp;&nbsp;&nbsp; 把CA签名后的server端证书导入keystore<br />keytool -import -v -alias tomcat_server -file tomcat_server.crt -storepass 123456 -keystore server_keystore<br />6)&nbsp;&nbsp;&nbsp; 查看server端证书<br />&nbsp;&nbsp; keytool -list -v -keystore server_keystore&nbsp;&nbsp;<br />&nbsp;可以看到tomcat_server的证书链长度是2<br />&nbsp;<br />4.&nbsp;&nbsp;&nbsp; 生成client端证书<br />1)&nbsp;&nbsp;&nbsp; 生成客户端CSR<br />&nbsp;&nbsp; openssl genrsa -des3 -out tomcat_client.key 1024<br />openssl req -new -key tomcat_client.key -out tomcat_client.csr -config openssl.cnf<br />2)&nbsp;&nbsp;&nbsp; 用CA私钥进行签名，也可以到权威机构申请CA签名<br />openssl ca -in tomcat_client.csr -out tomcat_client.crt -cert ca.crt -keyfile ca.key -notext -config openssl.cnf<br />3)&nbsp;&nbsp;&nbsp; 生成PKCS12格式证书<br />openssl pkcs12 -export -inkey tomcat_client.key -in tomcat_client.crt -out&nbsp; tomcat_client.p12<br />4)&nbsp;&nbsp;&nbsp; 使用Keytool列出pkcs12证书的内容：<br />&nbsp;&nbsp; keytool -rfc -list -keystore tomcat_client.p12 -storetype pkcs12</span></div><img src ="http://www.blogjava.net/jjshcc/aggbug/416086.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-07-22 14:42 <a href="http://www.blogjava.net/jjshcc/archive/2014/07/22/416086.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中的软引用，弱引用和虚引用</title><link>http://www.blogjava.net/jjshcc/archive/2014/03/21/411348.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Fri, 21 Mar 2014 09:01:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/03/21/411348.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/411348.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/03/21/411348.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/411348.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/411348.html</trackback:ping><description><![CDATA[<div><span style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; line-height: normal; "><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">SoftReference、Weak Reference和PhantomRefrence分析和比较</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　本文将谈一下对SoftReference（软引用）、WeakReference（弱引用）和PhantomRefrence（虚引用）的理解，这三个类是对heap中java对象的应用，通过这个三个类可以和gc做简单的交互。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "><strong style="word-break: break-all; line-height: normal !important; ">　　强引用：</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　除了上面提到的三个引用之外，还有一个引用，也就是最长用到的那就是强引用。例如：</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><table align="center" style="word-break: break-all; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #dddddd; border-bottom-color: #999999; border-bottom-style: solid; border-left-color: #999999; border-left-style: solid; width: 612px; border-top-color: #999999; border-top-style: solid; border-right-color: #999999; border-right-style: solid; "><tbody style="word-break: break-all; "><tr style="word-break: break-all; "><td style="font-size: 12px; word-break: break-all; ">Object o=new Object();&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />Object o1=o;&nbsp;&nbsp;</td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　上面代码中第一句是在heap堆中创建新的Object对象通过o引用这个对象，第二句是通过o建立o1到new Object()这个heap堆中的对象的引用，这两个引用都是强引用.只要存在对heap中对象的引用，gc就不会收集该对象.如果通过如下代码：</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><table align="center" style="word-break: break-all; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #dddddd; border-bottom-color: #999999; border-bottom-style: solid; border-left-color: #999999; border-left-style: solid; width: 612px; border-top-color: #999999; border-top-style: solid; border-right-color: #999999; border-right-style: solid; "><tbody style="word-break: break-all; "><tr style="word-break: break-all; "><td style="font-size: 12px; word-break: break-all; ">o=null;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />o1=null;</td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　如果显式地设置o和o1为null，或超出范围，则gc认为该对象不存在引用，这时就可以收集它了。可以收集并不等于就一会被收集，什么时候收集这要取决于gc的算法，这要就带来很多不确定性。例如你就想指定一个对象，希望下次gc运行时把它收集了，那就没办法了，有了其他的三种引用就可以做到了。其他三种引用在不妨碍gc收集的情况下，可以做简单的交互。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　heap中对象有强可及对象、软可及对象、弱可及对象、虚可及对象和不可到达对象。应用的强弱顺序是强、软、弱、和虚。对于对象是属于哪种可及的对象，由他的最强的引用决定。如下：</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><table align="center" style="word-break: break-all; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #dddddd; border-bottom-color: #999999; border-bottom-style: solid; border-left-color: #999999; border-left-style: solid; width: 612px; border-top-color: #999999; border-top-style: solid; border-right-color: #999999; border-right-style: solid; "><tbody style="word-break: break-all; "><tr style="word-break: break-all; "><td style="font-size: 12px; word-break: break-all; ">String abc=new String("abc");&nbsp; //1&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />SoftReference&lt;String&gt; abcSoftRef=new SoftReference&lt;String&gt;(abc);&nbsp; //2&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />WeakReference&lt;String&gt; abcWeakRef = new WeakReference&lt;String&gt;(abc); //3&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />abc=null; //4&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />abcSoftRef.clear();//5</td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　第一行在heap对中创建内容为&#8220;abc&#8221;的对象，并建立abc到该对象的强引用,该对象是强可及的。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　第二行和第三行分别建立对heap中对象的软引用和弱引用，此时heap中的对象仍是强可及的。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　第四行之后heap中对象不再是强可及的，变成软可及的。同样第五行执行之后变成弱可及的。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "><strong style="word-break: break-all; line-height: normal !important; ">　　SoftReference（软引用）</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　软引用是主要用于内存敏感的高速缓存。在jvm报告内存不足之前会清除所有的软引用，这样以来gc就有可能收集软可及的对象，可能解决内存吃紧问题，避免内存溢出。什么时候会被收集取决于gc的算法和gc运行时可用内存的大小。当gc决定要收集软引用是执行以下过程,以上面的abcSoftRef为例：</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　1、首先将abcSoftRef的referent设置为null，不再引用heap中的new String("abc")对象。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　2、将heap中的new String("abc")对象设置为可结束的(finalizable)。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　3、当heap中的new String("abc")对象的finalize()方法被运行而且该对象占用的内存被释放， abcSoftRef被添加到它的ReferenceQueue中。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　注:对ReferenceQueue软引用和弱引用可以有可无，但是虚引用必须有，参见：</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><table align="center" style="word-break: break-all; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #dddddd; border-bottom-color: #999999; border-bottom-style: solid; border-left-color: #999999; border-left-style: solid; width: 612px; border-top-color: #999999; border-top-style: solid; border-right-color: #999999; border-right-style: solid; "><tbody style="word-break: break-all; "><tr style="word-break: break-all; "><td style="font-size: 12px; word-break: break-all; ">Reference(T paramT, ReferenceQueue&lt;? super T&gt;paramReferenceQueue)&nbsp;&nbsp;</td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　被 Soft Reference 指到的对象，即使没有任何 Direct Reference，也不会被清除。一直要到 JVM 内存不足且 没有 Direct Reference 时才会清除，SoftReference 是用来设计 object-cache 之用的。如此一来 SoftReference 不但可以把对象 cache 起来，也不会造成内存不足的错误 （OutOfMemoryError）。我觉得 Soft Reference 也适合拿来实作 pooling 的技巧。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><table align="center" style="word-break: break-all; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #dddddd; border-bottom-color: #999999; border-bottom-style: solid; border-left-color: #999999; border-left-style: solid; width: 612px; border-top-color: #999999; border-top-style: solid; border-right-color: #999999; border-right-style: solid; "><tbody style="word-break: break-all; "><tr style="word-break: break-all; "><td style="font-size: 12px; word-break: break-all; "><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.8em !important; ">&nbsp;&nbsp;&nbsp;&nbsp; A obj = new A();<br style="word-break: break-all; line-height: normal !important; " />SoftRefenrence sr = new SoftReference(obj);</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.8em !important; ">&nbsp;&nbsp;&nbsp; //引用时<br style="word-break: break-all; line-height: normal !important; " />&nbsp;&nbsp;&nbsp; if(sr!=null){<br style="word-break: break-all; line-height: normal !important; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj = sr.get();<br style="word-break: break-all; line-height: normal !important; " />&nbsp;&nbsp;&nbsp; }else{<br style="word-break: break-all; line-height: normal !important; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obj = new A();<br style="word-break: break-all; line-height: normal !important; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sr = new SoftReference(obj);<br style="word-break: break-all; line-height: normal !important; " />&nbsp;&nbsp;&nbsp; }</p></td></tr></tbody></table><br /><div><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "><strong style="word-break: break-all; line-height: normal !important; ">　弱引用</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　当gc碰到弱可及对象，并释放abcWeakRef的引用，收集该对象。但是gc可能需要对此运用才能找到该弱可及对象。通过如下代码可以了明了的看出它的作用：</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><table align="center" style="word-break: break-all; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #dddddd; border-bottom-color: #999999; border-bottom-style: solid; border-left-color: #999999; border-left-style: solid; width: 612px; border-top-color: #999999; border-top-style: solid; border-right-color: #999999; border-right-style: solid; "><tbody style="word-break: break-all; "><tr style="word-break: break-all; "><td style="font-size: 12px; word-break: break-all; ">String abc=new String("abc");&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />WeakReference&lt;String&gt; abcWeakRef = new WeakReference&lt;String&gt;(abc);&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />abc=null;&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />System.out.println("before gc: "+abcWeakRef.get());&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />System.gc();&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />System.out.println("after gc: "+abcWeakRef.get());&nbsp;&nbsp;</td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　运行结果：</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　before gc: abc<br style="word-break: break-all; line-height: normal !important; " />　　after gc: null</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　gc收集弱可及对象的执行过程和软可及一样，只是gc不会根据内存情况来决定是不是收集该对象。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　如果你希望能随时取得某对象的信息，但又不想影响此对象的垃圾收集，那么你应该用 Weak Reference 来记住此对象，而不是用一般的 reference。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><table align="center" style="word-break: break-all; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #dddddd; border-bottom-color: #999999; border-bottom-style: solid; border-left-color: #999999; border-left-style: solid; width: 612px; border-top-color: #999999; border-top-style: solid; border-right-color: #999999; border-right-style: solid; "><tbody style="word-break: break-all; "><tr style="word-break: break-all; "><td style="font-size: 12px; word-break: break-all; "><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.8em !important; ">A obj = new A();</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.8em !important; ">&nbsp;&nbsp;&nbsp; WeakReference wr = new WeakReference(obj);</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.8em !important; ">&nbsp;&nbsp;&nbsp; obj = null;</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.8em !important; ">&nbsp;&nbsp;&nbsp; //等待一段时间，obj对象就会被垃圾回收<br style="word-break: break-all; line-height: normal !important; " />　　...</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 1.8em !important; ">　　if (wr.get()==null) {&nbsp;<br style="word-break: break-all; line-height: normal !important; " />　　System.out.println("obj 已经被清除了 ");&nbsp;<br style="word-break: break-all; line-height: normal !important; " />　　} else {&nbsp;<br style="word-break: break-all; line-height: normal !important; " />　　System.out.println("obj 尚未被清除，其信息是 "+obj.toString());<br style="word-break: break-all; line-height: normal !important; " />　　}<br style="word-break: break-all; line-height: normal !important; " />　　...<br style="word-break: break-all; line-height: normal !important; " />}</p></td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　在此例中，透过 get() 可以取得此 Reference 的所指到的对象，如果返回值为 null 的话，代表此对象已经被清除。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　这类的技巧，在设计 Optimizer 或 Debugger 这类的程序时常会用到，因为这类程序需要取得某对象的信息，但是不可以 影响此对象的垃圾收集。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "><strong style="word-break: break-all; line-height: normal !important; ">　　PhantomRefrence（虚引用）</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　虚顾名思义就是没有的意思，建立虚引用之后通过get方法返回结果始终为null，通过源代码你会发现，虚引用通向会把引用的对象写进referent，只是get方法返回结果为null。先看一下和gc交互的过程在说一下他的作用。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　1 不把referent设置为null，直接把heap中的new String("abc")对象设置为可结束的(finalizable).</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　2 与软引用和弱引用不同，先把PhantomRefrence对象添加到它的ReferenceQueue中，然后在释放虚可及的对象。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　你会发现在收集heap中的new String("abc")对象之前，你就可以做一些其他的事情。通过以下代码可以了解他的作用。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><table align="center" style="word-break: break-all; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #dddddd; border-bottom-color: #999999; border-bottom-style: solid; border-left-color: #999999; border-left-style: solid; width: 612px; border-top-color: #999999; border-top-style: solid; border-right-color: #999999; border-right-style: solid; "><tbody style="word-break: break-all; "><tr style="word-break: break-all; "><td style="font-size: 12px; word-break: break-all; ">import java.lang.ref.PhantomReference;&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />import java.lang.ref.Reference;&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />import java.lang.ref.ReferenceQueue;&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />import java.lang.reflect.Field;&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />public class Test {&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp; public static boolean isRun = true;&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception {&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String abc = new String("abc");&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(abc.getClass() + "@" + abc.hashCode());&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final ReferenceQueue referenceQueue = new ReferenceQueue&lt;String&gt;();&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Thread() {&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void run() {&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (isRun) {&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object o = referenceQueue.poll();&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (o != null) {&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Field rereferent = Reference.class&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .getDeclaredField("referent");&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rereferent.setAccessible(true);&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object result = rereferent.get(o);&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("gc will collect:"&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + result.getClass() + "@"&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + result.hashCode());&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e) {&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }.start();&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PhantomReference&lt;String&gt; abcWeakRef = new PhantomReference&lt;String&gt;(abc,&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; referenceQueue);&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; abc = null;&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.currentThread().sleep(3000);&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.gc();&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.currentThread().sleep(3000);&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isRun = false;&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />&nbsp;&nbsp;&nbsp;<br style="word-break: break-all; " />}</td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; "></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　结果为：</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; word-break: break-all; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 12px; text-align: left; background-color: #ffffff; ">　　class java.lang.String@96354<br style="word-break: break-all; line-height: normal !important; " />　　gc will collect:class java.lang.String@96354</p></div></span></div><img src ="http://www.blogjava.net/jjshcc/aggbug/411348.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-03-21 17:01 <a href="http://www.blogjava.net/jjshcc/archive/2014/03/21/411348.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Log4j每天生成日志文件和按文件大小生成日志文件</title><link>http://www.blogjava.net/jjshcc/archive/2014/03/12/410929.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Wed, 12 Mar 2014 03:27:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/03/12/410929.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/410929.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/03/12/410929.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/410929.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/410929.html</trackback:ping><description><![CDATA[<div><div>保存成日志文件形式的时候，大家经常会遇到一个问题：日志文件过大。上百兆的日志文件对 查阅日志信息来说也是一个问题。所以我希望能够每天或每个月产生一个日志文件，这样文件不至于过大。 或者根据日志文件大小来判断，超过规定大小，日志自动增加新文件。&nbsp;</div><div>在log4j中这两种方式的实现都很简单，只要在配置文件中设置即可。&nbsp;</div><div></div><div>一、按照一定时间产生日志文件,配置文件如下：&nbsp;</div><div># Set root logger level to ERROR and its only appender to A1.&nbsp;</div><div>log4j.rootLogger=ERROR,R&nbsp;</div><div></div><div># R is set to be a DailyRollingFileAppender.&nbsp;</div><div>log4j.appender.R=org.apache.log4j.DailyRollingFileAppender&nbsp;</div><div></div><div>log4j.appender.R.File=backup.log&nbsp;</div><div>log4j.appender.R.DatePattern = '.'yyyy-MM-dd&nbsp;</div><div>log4j.appender.R.layout=org.apache.log4j.PatternLayout&nbsp;</div><div>log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n&nbsp;</div><div></div><div>以上配置是每天产生一个备份文件。其中备份文件的名字叫backup.log。&nbsp;</div><div>具体的效果是这样：当天的日志信息记录在backup.log文件中，前一天的记录在名称为 backup.log.yyyy-mm-dd 的文件中。&nbsp;</div><div>类似的，如果需要每月产生一个文件可以修改上面的配置：&nbsp;</div><div>将&nbsp;</div><div>log4j.appender.R.DatePattern = '.'yyyy-MM-dd&nbsp;</div><div>改为&nbsp;</div><div>log4j.appender.R.DatePattern = '.'yyyy-MM&nbsp;</div><div></div><div>二、根据日志文件大小自动产生新日志文件&nbsp;</div><div>配置文件内容如下：&nbsp;</div><div></div><div># Set root logger level to ERROR and its only appender to A1.&nbsp;</div><div>log4j.rootLogger=ERROR,R&nbsp;</div><div></div><div># R is set to be a RollingFileAppender.&nbsp;</div><div>log4j.appender.R=org.apache.log4j.RollingFileAppender&nbsp;</div><div></div><div>log4j.appender.R.File=backup.log&nbsp;</div><div>#log4j.appender.R.MaxFileSize=100KB&nbsp;</div><div></div><div># Keep one backup file&nbsp;</div><div>log4j.appender.R.MaxBackupIndex=1&nbsp;</div><div>log4j.appender.R.layout=org.apache.log4j.PatternLayout&nbsp;</div><div>log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n&nbsp;</div><div></div><div></div><div>其中：&nbsp;</div><div>#日志文件的大小&nbsp;</div><div>log4j.appender.R.MaxFileSize=100KB&nbsp;</div><div># 保存一个备份文件&nbsp;</div><div>log4j.appender.R.MaxBackupIndex=1&nbsp;</div></div><img src ="http://www.blogjava.net/jjshcc/aggbug/410929.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-03-12 11:27 <a href="http://www.blogjava.net/jjshcc/archive/2014/03/12/410929.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>通过GC输出分析内存泄露问题</title><link>http://www.blogjava.net/jjshcc/archive/2014/03/05/410656.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Wed, 05 Mar 2014 09:09:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/03/05/410656.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/410656.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/03/05/410656.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/410656.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/410656.html</trackback:ping><description><![CDATA[<div><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px; ">SIP5.0以后服务的请求量爆发性增长，因此也暴露了原来没有暴露出来的问题。由于过去一般一个新版本发布周期在一个月左右，因此如果是小的内存泄露，在一个月之内重新发布以后也就看不出任何问题。&nbsp;<br /><br />因此这阵子除了优化Memcache客户端和SIP框架逻辑以外其他依赖部分以外，对于内存泄露的压力测试也开始实实在在的做起来。经过这次问题的定位和解决以后，大致觉得对于一个大用户量应用要放心的话，那么需要做这么几步。&nbsp;<br /><br />1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在GC输出的环境下，大压力下做多天的测试。（可以在 JAVA_OPTS增加-verbose:gc -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError）&nbsp;<br /><br />2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 检查GC输出日志来判断是否有内存泄露。（这部分后面有详细的实例说明）&nbsp;<br /><br />3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果出现内存泄露问题，则使用jprofiler等工具来排查内存泄露点（之所以不一开始使用，因为jprofiler等工具对于压力测试有影响，使得大压力无法上去，也使问题不那么容易暴露）&nbsp;<br /><br />4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 解决问题，并在重复2步骤。&nbsp;<br /><br />这里对SIP在jdk1.5和jdk1.6下做压力测试的GC 日志来做一个实际的分析对比，通过对比来大致描述一下如何根据输出情况能够了解应用是否存在内存泄露问题。（这里的内存泄露问题就是在以前blog写过的jdk的concurrent包内LinkedBlockingQueue的poll方法存在比较严重的内存泄露，调用频率越高，内存泄露的越厉害）&nbsp;<br /><br />两次压力测试都差不多都是两天，测试方案如下：&nbsp;<br /><br />开始50个并发，每个并发每次请求完毕后休息0.1秒，10分钟后增长50个并发，按此规律增长到500并发。&nbsp;<br /><br />旧版本SIP是在JDK1.5环境下完成的压力测试，&nbsp;<br /><br />新版本SIP的JDK版本是1.6，&nbsp;<br /><br />压力机和以前一样，是10.2.226.40，DELL1950，8CPU，8G内存。&nbsp;<br /><br />压力机模拟发出对一个需要签名的API不断的调用请求。&nbsp;<br /><br />看看两个Log的具体内容（内容很多截取部分做分析）&nbsp;<br /><br />先说一下日志输出的结构：(1.6和1.5略微有一些不同，只是1.6对于时间统计更加细致)&nbsp;<br /><br />[GC [&lt;collector&gt;: &lt;starting occupancy1&gt; -&gt; &lt;ending occupancy1&gt;, &lt;pause time1&gt; secs] &lt;starting occupancy3&gt; -&gt; &lt;ending occupancy3&gt;, &lt;pause time3&gt; secs]&nbsp;<br /><br />&lt;collector&gt;GC收集器的名称&nbsp;<br /><br />&lt;starting occupancy1&gt; 新生代在GC前占用的内存&nbsp;<br /><br />&lt;ending occupancy1&gt; 新生代在GC后占用的内存&nbsp;<br /><br />&lt;pause time1&gt; 新生代局部收集时jvm暂停处理的时间&nbsp;<br /><br />&lt;starting occupancy3&gt; JVM Heap 在GC前占用的内存&nbsp;<br /><br />&lt;ending occupancy3&gt; JVM Heap 在GC后占用的内存&nbsp;<br /><br />&lt;pause time3&gt; GC过程中jvm暂停处理的总时间&nbsp;<br /><br />Jdk1.5 log：&nbsp;<br /><br />启动时GC输出：&nbsp;<br /><br />[GC [DefNew: 209792K-&gt;4417K(235968K), 0.0201630 secs] 246722K-&gt;41347K(498112K), 0.0204050 secs]&nbsp;<br /><br />[GC [DefNew: 214209K-&gt;4381K(235968K), 0.0139200 secs] 251139K-&gt;41312K(498112K), 0.0141190 secs]&nbsp;<br /><br />一句输出：&nbsp;<br /><br />新生代回收前209792K，回收后4417K，回收数量205375K，Heap总量回收前246722K回收后41347K，回收总量205375K。这就表示100%的收回，没有任何新生代的对象被提升到中生代或者永久区（名字说的不一定准确，只是表达意思）。&nbsp;<br /><br />第二句输出：&nbsp;<br /><br />按照分析也就只是有1K内容被提升到中生代。&nbsp;<br /><br />运行一段时间后：&nbsp;<br /><br />[GC [DefNew: 210686K-&gt;979K(235968K), 0.0257140 secs] 278070K-&gt;68379K(498244K), 0.0261820 secs]&nbsp;<br /><br />[GC [DefNew: 210771K-&gt;1129K(235968K), 0.0275160 secs] 278171K-&gt;68544K(498244K), 0.0280050 secs]&nbsp;<br /><br />第一句输出：&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新生代回收前210686K，回收后979K，回收数量209707K，Heap总量回收前278070K回收后68379K，回收总量209691K。这就表示有16k没有被回收。&nbsp;<br /><br />第二句输出：&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新生代回收前210771K，回收后1129K，回收数量209642K，Heap总量回收前278171K回收后68544K，回收总量209627K。这就表示有15k没有被回收。&nbsp;<br /><br />比较一下启动时与现在的新生代占用内存情况和Heap使用情况发现Heap的使用增长很明显，新生代没有增长，而Heap使用总量增长了27M，这就表明可能存在内存泄露，虽然每一次泄露的字节数很少，但是频率很高，大部分泄露的对象都被升级到了中生代或者持久代。&nbsp;<br /><br />又一段时间后：&nbsp;<br /><br />[GC [DefNew: 211554K-&gt;1913K(235968K), 0.0461130 secs] 350102K-&gt;140481K(648160K), 0.0469790 secs]&nbsp;<br /><br />[GC [DefNew: 211707K-&gt;2327K(235968K), 0.0546170 secs] 350275K-&gt;140921K(648160K), 0.0555070 secs]&nbsp;<br /><br />第一句输出：&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新生代回收前211554K，回收后1913K，回收数量209641K，Heap总量回收前350102K回收后140481K，回收总量209621K。这就表示有20k没有被回收。&nbsp;<br /><br /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 分析到这里就可以看出每一次泄露的内存只有10几K，但是在大压力长时间的测试下，内存泄露还是很明显的，此时Heap已经增长到了140M，较启动时已经增长了100M。同时GC占用的时间越来越长。&nbsp;<br /><br />后续的现象：&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 后续观察日志会发现，Full GC的频率越来越高，收集所花费时间也是越来越长。（Full GC定期会执行，同时局部回收不能满足分配需求的情况下也会执行）。&nbsp;<br /><br /><br /><br />[Full GC [Tenured: 786431K-&gt;786431K(786432K), 3.4882390 secs] 1022399K-&gt;1022399K(1022400K), [Perm : 36711K-&gt;36711K(98304K)], 3.4887920 secs]&nbsp;<br /><br />java.lang.OutOfMemoryError: Java heap space&nbsp;<br /><br />Dumping heap to java_pid7720.hprof ...&nbsp;<br /><br /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 出现这个语句表示内存真的被消耗完了。&nbsp;<br /><br />Jdk1.6 log：&nbsp;<br /><br /><br /><br />启动时GC的输出：&nbsp;<br /><br />[GC [PSYoungGen: 221697K-&gt;31960K(229376K)] 225788K-&gt;36051K(491520K), 0.0521830 secs] [Times: user=0.26 sys=0.05, real=0.05 secs]&nbsp;<br /><br />[GC [PSYoungGen: 228568K-&gt;32752K(229376K)] 232659K-&gt;37036K(491520K), 0.0408620 secs] [Times: user=0.21 sys=0.02, real=0.04 secs]&nbsp;<br /><br /><br /><br />第一句输出：&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新生代回收前221697K，回收后31960K，回收数量189737K，Heap总量回收前225788K回收后36051K，回收总量189737K。100%被回收。&nbsp;<br /><br /><br /><br />运行一段时间后输出：&nbsp;<br /><br />[GC [PSYoungGen: 258944K-&gt;2536K(259328K)] 853863K-&gt;598135K(997888K), 0.0471620 secs] [Times: user=0.15 sys=0.00, real=0.05 secs]&nbsp;<br /><br />[GC [PSYoungGen: 259048K-&gt;2624K(259328K)] 854647K-&gt;598907K(997888K), 0.0462980 secs] [Times: user=0.16 sys=0.02, real=0.04 secs]&nbsp;<br /><br /><br /><br />第一句输出：&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新生代回收前258944K，回收后2536K，回收数量256408K，Heap总量回收前853863K回收后598135K，回收总量255728K。680K没有被回收，但这并不意味着就会产生内存泄露。同时可以看出GC回收时间并没有增加。&nbsp;<br /><br /><br /><br />在运行一段时间后输出：&nbsp;<br /><br />[GC [PSYoungGen: 258904K-&gt;2488K(259264K)] 969663K-&gt;713923K(1045696K), 0.0485140 secs] [Times: user=0.16 sys=0.01, real=0.04 secs]&nbsp;<br /><br />[GC [PSYoungGen: 258872K-&gt;2448K(259328K)] 970307K-&gt;714563K(1045760K), 0.0473770 secs] [Times: user=0.16 sys=0.01, real=0.05 secs]&nbsp;<br /><br /><br /><br />第一句输出：&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新生代回收前258904K，回收后2488K，回收数量256416K，Heap总量回收前969663K回收后713923K，回收总量255740K。676K没有被回收，同时总的Heap也有所增加。&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 此时看起来好像和1.5的状况一样。但是查看了一下Full GC的执行还是400-500次GC执行一次，因此继续观察。&nbsp;<br /><br /><br /><br />运行一天多以后输出：&nbsp;<br /><br />[GC [PSYoungGen: 257016K-&gt;3304K(257984K)] 1019358K-&gt;766310K(1044416K), 0.0567120 secs] [Times: user=0.18 sys=0.01, real=0.06 secs]&nbsp;<br /><br />[GC [PSYoungGen: 257128K-&gt;2920K(258112K)] 1020134K-&gt;766622K(1044544K), 0.0549570 secs] [Times: user=0.19 sys=0.00, real=0.05 secs]&nbsp;<br /><br /><br /><br />可以发现Heap增长趋缓。&nbsp;<br /><br /><br /><br />运行两天以后输出：&nbsp;<br /><br />[GC [PSYoungGen: 256936K-&gt;3584K(257792K)] 859561K-&gt;606969K(1044224K), 0.0565910 secs] [Times: user=0.18 sys=0.01, real=0.06 secs]&nbsp;<br /><br />[GC [PSYoungGen: 256960K-&gt;3368K(257728K)] 860345K-&gt;607445K(1044160K), 0.0553780 secs] [Times: user=0.18 sys=0.01, real=0.06 secs]&nbsp;<br /><br /><br /><br />发现Heap反而减少了，此时可以对内存泄露问题作初步排除了。（其实在jdk1.6环境下用jprofiler来观察，对于concurrent那个内存泄露点的跟踪发现，内存的确还是会不断增长的，不过在一段时间后还是有回收，因此也就可以部分解释前面出现的情况）&nbsp;<br /><br /><br /><br />总结：&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于GC输出的观察需要分两个维度来看。一个是纵向比较，也就是一次回收对于内存变化的观察。一个是横向比较，对于长时间内存分配占用情况的比较，这部分比较需要较长时间的观察，不能仅仅凭短时间的几个抽样比较，因为对于抽样来说，Full GC前后的区别，运行时长的区别，资源瞬时占用的区别都会影响判断。同时要结合Full GC发生的时间周期，每一次GC收集所耗费的时间作为辅助判断标准。&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 顺便说一下，Heap的 YoungGen,OldGen,PermGen的设置也是需要注意的，并不是越大越好，越大执行收集的时间越久，但是可能执行Full GC的频率会比较低，因此需要权衡。这些仔细的去了解一下GC的基础设计思想会更有帮助，不过一般用默认的也不错。还有就是可以配置一些特殊的GC，并行，同步等等，充分利用多CPU的资源。&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于GC的优化可以通过现在很多图形工具来做，也可以类似于我这样采用最原始的分析方式，好处就是任何时间任何地点只要知道原理就可以分析无需借助外部工具。原始的总是最好的^_^。&nbsp;</span></div><img src ="http://www.blogjava.net/jjshcc/aggbug/410656.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-03-05 17:09 <a href="http://www.blogjava.net/jjshcc/archive/2014/03/05/410656.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>探秘Java虚拟机 gc的监控</title><link>http://www.blogjava.net/jjshcc/archive/2014/03/05/410655.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Wed, 05 Mar 2014 09:03:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/03/05/410655.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/410655.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/03/05/410655.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/410655.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/410655.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1、Java虚拟机运行时的数据区2、常用的内存区域调节参数-Xms：初始堆大小，默认为物理内存的1/64(&lt;1GB)；默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时，JVM就会增大堆直到-Xmx的最大限制-Xmx：最大堆大小，默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时，JVM会减少堆直到 -Xms的最小限制-Xmn：新生代的内存空间...&nbsp;&nbsp;<a href='http://www.blogjava.net/jjshcc/archive/2014/03/05/410655.html'>阅读全文</a><img src ="http://www.blogjava.net/jjshcc/aggbug/410655.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-03-05 17:03 <a href="http://www.blogjava.net/jjshcc/archive/2014/03/05/410655.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>gc日志分析工具</title><link>http://www.blogjava.net/jjshcc/archive/2014/03/05/410653.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Wed, 05 Mar 2014 08:58:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/03/05/410653.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/410653.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/03/05/410653.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/410653.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/410653.html</trackback:ping><description><![CDATA[<div><span style="font-family: Arial; line-height: 26px; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><span style="font-family: 宋体; ">性能测试排查定位问题，分析调优过程中，会遇到要分析</span><span style="font-family: 宋体; ">gc</span><span style="font-family: 宋体; ">日志，人肉分析</span><span style="font-family: 宋体; ">gc</span><span style="font-family: 宋体; ">日志有时比较困难，相关图形化或命令行工具可以有效地帮助辅助分析。</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">Gc</span><span style="font-family: 宋体; ">日志参数</span></strong></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">通过在tomcat启动脚本中添加相关参数生成gc日志</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">-verbose.gc</span></strong><span style="font-family: 宋体; ">开关可显示GC的操作内容。打开它，可以显示最忙和最空闲收集行为发生的时间、收集前后的内存大小、收集需要的时间等。</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; ">打开<strong>-xx:+ printGCdetails</strong>开关，可以详细了解GC中的变化。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; ">打开<strong>-XX: + PrintGCTimeStamps</strong>开关，可以了解这些垃圾收集发生的时间，自JVM启动以后以秒计量。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; ">最后，通过<strong>-xx: + PrintHeapAtGC</strong>开关了解堆的更详细的信息。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; ">为了了解新域的情况，可以通过<strong>-XX:=PrintTenuringDistribution</strong>开关了解获得使用期的对象权。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">-Xloggc:$CATALINA_BASE/logs/gc.log</span></strong><span style="font-family: 宋体; ">&nbsp;gc</span><span style="font-family: 宋体; ">日志产生的路径</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">XX:+PrintGCApplicationStoppedTime</span></strong><span style="font-family: 宋体; ">&nbsp;//&nbsp;</span><span style="font-family: 宋体; ">输出GC造成应用暂停的时间</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">-XX:+PrintGCDateStamps</span></strong><span style="font-family: 宋体; ">&nbsp;// GC</span><span style="font-family: 宋体; ">发生的时间信息</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">Gc</span><span style="font-family: 宋体; ">日志</span></strong></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><img src="http://img.my.csdn.net/uploads/201211/26/1353893863_7743.jpg" alt="" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; max-width: 100%; " /><br /></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; ">日志中显示了gc发生的时间，young区回收情况，整体回收情况，fullGC情况，回收所消耗时间等</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong>&nbsp;</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">常用JVM参数</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">分析gc日志后，经常需要调整jvm内存相关参数，常用参数如下</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">-Xms</span><span style="font-family: 宋体; ">：</span></strong><span style="font-family: 宋体; ">初始堆大小，默认为物理内存的1/64(&lt;1GB)；默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时，JVM就会增大堆直到-Xmx的最大限制</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">-Xmx</span></strong><span style="font-family: 宋体; ">：最大堆大小，默</span><span style="font-family: 宋体; ">认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时，JVM会</span><span style="font-family: 宋体; ">减少堆直到&nbsp;-Xms的最小限制</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">-Xmn</span><span style="font-family: 宋体; ">：</span></strong><span style="font-family: 宋体; ">新生代的内存空间大小，注意：此处的大小是（eden+ 2 survivor space)。与jmap -heap中显示的New gen是不同的。整个堆大小=新生代大小&nbsp;+&nbsp;老生代大小&nbsp;+&nbsp;永久代大小。&nbsp;<br />在保证堆大小不变的情况下，增大新生代后,将会减小老生代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">-XX:SurvivorRatio</span><span style="font-family: 宋体; ">：</span></strong><span style="font-family: 宋体; ">新生代中Eden区域与Survivor区域的容量比值，默认值为8。两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10。</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">-Xss</span><span style="font-family: 宋体; ">：</span></strong><span style="font-family: 宋体; ">每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。应根据应用的线程所需内存大小进行适当调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的，不能无限生成，经验值在3000~5000左右。一般小的应用， 如果栈不是很深， 应该是128k够用的，大的应用建议使用256k。这个选项对性能影响比较大，需要严格的测试。和threadstacksize选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:"-Xss is translated in a VM flag named ThreadStackSize&#8221;一般设置这个值就可以了。</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">-XX:PermSize</span><span style="font-family: 宋体; ">：</span></strong><span style="font-family: 宋体; ">设置永久代(perm gen)初始值。默认值为物理内存的1/64。</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">-XX:MaxPermSize</span><span style="font-family: 宋体; ">：</span></strong><span style="font-family: 宋体; ">设置持久代最大值。物理内存的1/4。</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong>&nbsp;</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">Gc</span><span style="font-family: 宋体; ">日志分析工具</span></strong></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">(1)GCHisto</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; "><a rel="nofollow" href="http://java.net/projects/gchisto" style="color: #ff9900; text-decoration: none; ">http://java.net/projects/gchisto</a></span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong>&nbsp;</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">直接点击gchisto.jar就可以运行，点add载入gc.log</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">统计了总共gc次数，youngGC次数，FullGC次数，次数的百分比，GC消耗的时间，百分比，平均消耗时间，消耗时间最小最大值等</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "></p><div style="line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><img src="http://img.my.csdn.net/uploads/201211/26/1353893879_4234.jpg" alt="" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; max-width: 100%; " /></div>&nbsp;<p align="left" style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: -90pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; "><span style="font-family: 宋体; "><span style="background-color: #ffffff; "><strong><br /></strong></span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; ">统计的图形化表示</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "></p><div style="line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><img src="http://img.my.csdn.net/uploads/201211/26/1353893896_6226.jpg" alt="" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; max-width: 100%; " /></div>&nbsp;<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><span style="font-family: 宋体; ">YoungGC,FullGC</span><span style="font-family: 宋体; ">不同消耗时间上次数的分布图，勾选可以显示youngGC或fullGC单独的分布情况</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "></p><div style="line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><img src="http://img.my.csdn.net/uploads/201211/26/1353893925_4266.jpg" alt="" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; max-width: 100%; " /></div>&nbsp;<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; ">整个时间过程详细的gc情况，可以对整个过程进行剖析</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "></p><div style="line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><img src="http://img.my.csdn.net/uploads/201211/26/1353893944_8263.jpg" alt="" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; max-width: 100%; " /></div>&nbsp;<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">(2)GCLogViewer</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong>&nbsp;</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; "><a rel="nofollow" href="http://code.google.com/p/gclogviewer/" style="color: #ff9900; text-decoration: none; ">http://code.google.com/p/gclogviewer/</a></span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong>&nbsp;</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">点击run.bat运行</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong>&nbsp;</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">整个过程gc情况的趋势图，还显示了gc类型，吞吐量，平均gc频率，内存变化趋势等</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><strong><span style="font-family: 宋体; ">Tools</span><span style="font-family: 宋体; ">里还能比较不同gc日志</span></strong></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; "><br /></span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "></p><div style="line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><img src="http://img.my.csdn.net/uploads/201211/26/1353893963_8258.jpg" alt="" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; max-width: 100%; " /></div>&nbsp;<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; "><br /></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">(3)HPjmeter</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong>&nbsp;</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><span style="line-height: 23px; font-size: 10pt; font-family: 宋体; ">获取地址</span><span style="line-height: 23px; font-size: 10pt; ">&nbsp;<a rel="nofollow" href="http://www.hp.com/go/java" style="color: #ff9900; text-decoration: none; ">http://www.hp.com/go/java</a><br /></span><span style="line-height: 23px; font-size: 10pt; font-family: 宋体; ">参考文档</span><span style="line-height: 23px; font-size: 10pt; ">&nbsp;<a rel="nofollow" href="http://www.javaperformancetuning.com/tools/hpjtune/index.shtml" style="color: #ff9900; text-decoration: none; ">http://www.javaperformancetuning.com/tools/hpjtune/index.shtml</a></span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong>&nbsp;</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; ">工具很强大，但只能打开由以下参数生成的GC log，&nbsp;-verbose:gc -Xloggc:gc.log,添加其他参数生成的gc.log无法打开。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">(4)GCViewer</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">http://www.tagtraum.com/gcviewer.html</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><span style="line-height: 21px; font-size: 9pt; font-family: 宋体; ">这个工具用的挺多的，但只能在</span><span style="line-height: 21px; font-size: 9pt; ">JDK1.5</span><span style="line-height: 21px; font-size: 9pt; font-family: 宋体; ">以下的版本中运行，</span><span style="line-height: 21px; font-size: 9pt; ">1.6</span><span style="line-height: 21px; font-size: 9pt; font-family: 宋体; ">以后没有对应。</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">(5)garbagecat</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; "><a rel="nofollow" href="http://code.google.com/a/eclipselabs.org/p/garbagecat/wiki/Documentation" style="color: #ff9900; text-decoration: none; ">http://code.google.com/a/eclipselabs.org/p/garbagecat/wiki/Documentation</a></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><strong><span style="font-family: 宋体; background-color: #ffffff; ">其它监控方法</span></strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><span style="font-family: 宋体; ">Jvisualvm</span><span style="font-family: 宋体; ">动态分析jvm内存情况和gc情况，插件：visualGC</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "></p><div style="line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><img src="http://img.my.csdn.net/uploads/201211/26/1353893984_8005.jpg" alt="" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; max-width: 100%; " /></div><span style="background-color: #ffffff; "><span style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; line-height: 25px; text-align: left; ">&nbsp;<img src="http://img.my.csdn.net/uploads/201211/26/1353894000_9349.jpg" alt="" style="border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; max-width: 100%; " /></span>&nbsp;</span><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><span style="font-family: 宋体; ">jvisualvm</span><span style="font-family: 宋体; ">还可以heapdump出对应hprof文件（默认存放路径：监控的服务器&nbsp;/tmp下），利用相关工具，比如HPjmeter可以对其进行分析</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><span style="font-family: 宋体; ">grep Full gc.log</span><span style="font-family: 宋体; ">粗略观察FullGC发生频率</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; ">jstat &#8211;gcutil [pid] [intervel] [count]</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><span style="font-family: 宋体; ">jmap -histo pid</span><span style="font-family: 宋体; ">可以观测对象的个数和占用空间<br />jmap -heap pid可以观测jvm配置参数，堆内存各区使用情况</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="background-color: #ffffff; "><span style="font-family: 宋体; ">jprofiler,jmap dump</span><span style="font-family: 宋体; ">出来用MAT分析</span></span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; ">&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; ">如果要分析的dump文件很大的话，就需要很多内存，很容易crash。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 25px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; text-align: left; "><span style="font-family: 宋体; background-color: #ffffff; ">所以在启动时，我们应该加上一些参数：&nbsp;Java&nbsp;&#8211;Xms512M&nbsp;&#8211;Xmx1024M&nbsp;&#8211;Xss8M&nbsp;</span></p></span></div><img src ="http://www.blogjava.net/jjshcc/aggbug/410653.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-03-05 16:58 <a href="http://www.blogjava.net/jjshcc/archive/2014/03/05/410653.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>查看JVM所有可用的Java security provider</title><link>http://www.blogjava.net/jjshcc/archive/2014/02/27/410383.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Thu, 27 Feb 2014 06:26:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/02/27/410383.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/410383.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/02/27/410383.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/410383.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/410383.html</trackback:ping><description><![CDATA[<div><div>&lt;%@ page import="java.security.Provider"%&gt;</div><div>&lt;%@ page import="java.security.Security"%&gt;</div><div>&lt;%@ page import="java.util.Set"%&gt;</div><div>&lt;%@ page import="java.util.Iterator"%&gt;</div><div>&lt;%</div><div>Provider[] providers = Security.getProviders();</div><div>for (int i = 0; i &lt; providers.length; i++) {</div><div><span style="white-space:pre">	</span>Provider provider = providers[i];</div><div><span style="white-space:pre">	</span>%&gt;&nbsp;</div><div><span style="white-space:pre">	</span> &nbsp; Provider name: &nbsp;&lt;%=provider.getName()%&gt;&lt;br/&gt;</div><div><span style="white-space:pre">	</span> &nbsp; Provider information: &nbsp;&lt;%=provider.getInfo()%&gt; &lt;br/&gt;</div><div><span style="white-space:pre">	</span> &nbsp; Provider version: &nbsp;&lt;%=provider.getVersion()%&gt;&lt;br/&gt;</div><div><span style="white-space:pre">	</span>&lt;%</div><div><span style="white-space:pre">	</span>Set entries = provider.entrySet();</div><div><span style="white-space:pre">	</span>Iterator iterator = entries.iterator();</div><div><span style="white-space:pre">	</span>while (iterator.hasNext()) {</div><div><span style="white-space:pre">		</span>%&gt;</div><div><span style="white-space:pre">		</span>Property entry:&lt;%=iterator.next()%&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;</div><div><span style="white-space:pre">		</span>&lt;%</div><div><span style="white-space:pre">	</span>}</div><div>}</div><div></div><div>%&gt;&nbsp;</div><div>&nbsp;</div></div><img src ="http://www.blogjava.net/jjshcc/aggbug/410383.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-02-27 14:26 <a href="http://www.blogjava.net/jjshcc/archive/2014/02/27/410383.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Java 中switch-case的注意地方</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/06/408573.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Mon, 06 Jan 2014 06:59:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/06/408573.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408573.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/06/408573.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408573.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408573.html</trackback:ping><description><![CDATA[<div><span style="font-family: Arial; line-height: 26px; color: #333333; "><div><span style="font-family: 宋体; ">下面是switch的简单写法：</span></div><span style="font-family: 宋体; ">switch（<span style="color: #ff0000; ">A</span>）{</span><div><span style="font-family: 宋体; ">case&nbsp;<span style="color: #ff0000; ">B</span>;</span></div><div><span style="font-family: 宋体; ">}</span></div><div><span style="font-family: 宋体; ">A部分中的值必须是int型的，或者是能够自动进行饮试转换成int型的表达式。也就是说A部分可以是byte/short/char/int型的。</span></div><div><span style="font-family: 宋体; ">其次要强调的是该程序中B部分的值必须是单个byte/short/char/int型的值，或者是final型的变量。</span></div><div><span style="font-family: 宋体; ">但是final型的变量也是有要求的，也即是它必须是编译时的常量，怎么讲呢，看下面的程序段：</span></div><div><span style="font-family: 宋体; ">final int a = 0;</span></div><div><span style="font-family: 宋体; ">final int b;</span></div><div><span style="font-family: 宋体; ">第二个语句就是在编译时不能够被识别出值的变量，因为它没有初始化，当然，这条语句也是错误的。</span></div><div><span style="font-family: 宋体; ">所以总结case后的值可以是常数值或final型的值。</span></div><div><span style="font-family: 宋体; "><br /></span></div><div><span style="font-family: 宋体; ">再看下面的程序段：</span></div><div><span style="font-family: 宋体; "><br /></span></div><div><div><span style="font-family: 宋体; ">public class TestSwitch {</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">	</span></span><span style="font-family: 宋体; ">public static void main(String[] args){</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">byte a = 11;</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">switch(a){//&nbsp;<span style="color: #ff0000; ">C</span></span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">case 11 : System.out.println(" 11 "); break;</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">case&nbsp;<span style="color: #ff00ff; ">225</span>&nbsp;: System.out.println(" 11 "); break;//&nbsp;<span style="color: #ff0000; ">D</span></span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">}</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">	</span></span><span style="font-family: 宋体; ">}</span></div><div><span style="font-family: 宋体; ">}</span></div><div><span style="font-family: 宋体; "><br /></span></div><div><span style="font-family: 宋体; ">该代码正确吗？答案是否定的。虽然在 C 处是合法的也即是byte型的a值可以出现在switch中，但是 D处的语句也即是第二个case后的值是225大小超过了byte的范围，所以是错误的。</span><span style="color: #ff0000; "><span style="font-family: 宋体; ">再就是case后的值不能出现重复</span></span><span style="font-family: 宋体; ">。因此在使用中要注意。</span></div><div><span style="font-family: 宋体; "><br /></span></div><div><span style="font-family: 宋体; ">=====================</span></div><div><span style="font-family: 宋体; ">再就是在使用switch-case中最容易忽视的就是忘记在每个case后处理完后忘记写上break；语句。那它带来的后果是什么呢，下面小程序段会告诉你：</span></div><div><div><span style="font-family: 宋体; ">public class TestSwitchCase {</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">	</span></span><span style="font-family: 宋体; ">public static void main(String[] args){</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">byte a = 2;</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">switch(a){</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">case 1 : System.out.println(" A ");</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">case 2 : System.out.println(" B ");</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">case 3 : System.out.println(" C ");</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">case 4 : System.out.println(" D ");</span></div><div><span style="font-family: 宋体; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default : System.out.println(" default ");<br /></span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">		</span></span><span style="font-family: 宋体; ">}</span></div><div><span style="white-space: pre; "><span style="font-family: 宋体; ">	</span></span><span style="font-family: 宋体; ">}</span></div><div><span style="font-family: 宋体; ">}</span></div></div><div><span style="font-family: 宋体; ">=========输出结果为:</span></div><div><div><div><span style="font-family: 宋体; ">&nbsp;B&nbsp;</span></div><div><span style="font-family: 宋体; ">&nbsp;C&nbsp;</span></div><div><span style="font-family: 宋体; ">&nbsp;D&nbsp;</span></div><div><span style="font-family: 宋体; ">&nbsp;default&nbsp;</span></div></div><div><span style="font-family: 宋体; ">--------------------------</span></div><div><span style="font-family: 宋体; ">看到了吗？连default都执行，注意结束符break;就OK了。</span></div></div></div></span></div><img src ="http://www.blogjava.net/jjshcc/aggbug/408573.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-06 14:59 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/06/408573.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中的数组长度问题</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/06/408556.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Mon, 06 Jan 2014 03:40:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/06/408556.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408556.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/06/408556.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408556.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408556.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;之前对java中的数组一直是一知半解，特别是数组中的长度问题。今天对这个问题也算是小有理解，算是对java数组的有了更进一步的了解吧。不说了，先来例子再说：&nbsp;[java]&nbsp;view plaincopypackage&nbsp;com.test;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;class&nbsp;Test&nbsp;{&nbs...&nbsp;&nbsp;<a href='http://www.blogjava.net/jjshcc/archive/2014/01/06/408556.html'>阅读全文</a><img src ="http://www.blogjava.net/jjshcc/aggbug/408556.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-06 11:40 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/06/408556.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Checked Exception与Runtime Exception 的区别</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/06/408553.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Mon, 06 Jan 2014 03:33:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/06/408553.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408553.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/06/408553.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408553.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408553.html</trackback:ping><description><![CDATA[<div><div>&nbsp;&nbsp; &nbsp; &nbsp; java里有个很重要的特色是Exception ，也就是说答应程序产生例外状况。而在学Java 的时候，我们也只知道Exception 的写法，却未必真能了解不同种类的Exception 的区别。</div><div></div><div>　　首先，您应该知道的是Java 提供了两种Exception 的模式，一种是执行的时候所产生的Exception (Runtime Exception)，另外一种则是受控制的Exception (Checked Exception)。</div><div></div><div>　　所有的Checked Exception 均从java.lang.Exception 继续而来，而Runtime Exception 则继续java.lang.RuntimeException 或java.lang.Error (实际上java.lang.RuntimeException 的上一层也是java.lang.Exception)。</div><div></div><div>　　当我们撰写程序的时候，我们很可能会对选择某种形式的Exception 感到困扰，到底我应该选择Runtime Exception 还是Checked Exception ？</div><div></div><div>　　其实，在运作上，我们可以通过Class 的Method 如何产生某个Exception以及某个程序如何处理这个被产生来的Exception 来了解它们之间的差异。</div><div>首先我们先建立一个Exception</div><div></div><div>public class CException extends Exception</div><div>{</div><div>public CException() {}</div><div>public CException(String message)</div><div>{</div><div>super(message);</div><div>}</div><div>}</div><div></div><div>然后我们撰写一个可能产生 CException 的 Class</div><div></div><div>public class testException</div><div>{</div><div>public void method1() throws CException</div><div>{</div><div>throw new CException("Test Exception");</div><div>}</div><div></div><div>public void method2(String msg)</div><div>{</div><div>if(msg == null)</div><div>{</div><div>throw new NullPointerException("Message is null");</div><div>}</div><div>}</div><div></div><div>public void method3() throws CException</div><div>{</div><div>method1();</div><div>}</div><div></div><div>// 以下省略</div><div>// ...</div><div>}</div><div></div><div>　　在这三个method 中，我们看到了method1 和method2 的程序码内都会产生Exception，但method3 的程序码中(大括号内)，并没产生Exception，但在method3 的定义中，暗示了这个method 可能产生CException。</div><div></div><div>呼叫method1() 的程序，必须将method1() 包含在try 与catch 中，如：</div><div></div><div>public class runtest</div><div>{</div><div>// ....</div><div>public static void main(String argv[])</div><div>{</div><div>testException te = new testException();</div><div>try</div><div>{</div><div>te.method1();</div><div>}</div><div>catch(CException ce)</div><div>{</div><div>// ....</div><div>}</div><div>}</div><div>// ...</div><div>}</div><div></div><div>　　虽然包含在try 与catch 中，并不表示这段程序码一定会收到CException，但它的用意在于提醒呼叫者，执行这个method 可能产生的意外，而使用者也必须要能针对这个意外做出相对应的处理方式。</div><div></div><div>　　当使用者呼叫method2() 时，并不需要使用try 和catch 将程序码包起来，因为method2 的定义中，并没有throws 任何的Exception ，如：</div><div></div><div>public class runtest</div><div>{</div><div>// ....</div><div>public static void main(String argv[])</div><div>{</div><div></div><div>testException te = new testException();</div><div></div><div>// 不会产生 Exception</div><div>te.method2("Hello");</div><div></div><div>// 会产生 Exception</div><div>te.method2(null);</div><div>}</div><div>// ...</div><div>}</div><div></div><div>　　程序在执行的时候，也不见得会真的产生NullPointerException ，这种Exception 叫做runtime exception 也有人称为unchecked exception ，产生Runtime Exception 的method (在这个范例中是method2) 并不需要在宣告method 的时候定义它将会产生哪一种Exception 。</div><div></div><div>在testException 的method3() 中，我们看到了另外一种状况，也就是method3里呼叫了method1() ，但却没有将method1 包在try 和catch 之间。相反，在method3() 的定义中，它定义了CException，实际上就是假如method3 收到了CException ，它将不处理这个CException ，而将它往外丢。当然，由于method3 的定义中有throws CException ，因此呼叫method3 的程序码也需要有try catch 才行。</div><div></div><div>　　因此从程序的运作机制上看，Runtime Exception与Checked Exception 不一样，然而从逻辑上看，Runtime Exception 与Checked Exception 在使用的目的上也不一样。</div><div></div><div>　　一般而言，Checked Exception 表示这个Exception 必须要被处理，也就是说程序设计者应该已经知道可能会收到某个Exception(因为要try catch住) ，所以程序设计者应该能针对这些不同的Checked Exception 做出不同的处理。</div></div><img src ="http://www.blogjava.net/jjshcc/aggbug/408553.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-06 11:33 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/06/408553.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java定义二维数组的几种写法</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/03/408417.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Fri, 03 Jan 2014 03:16:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/03/408417.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408417.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/03/408417.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408417.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408417.html</trackback:ping><description><![CDATA[<div><div>Java定义二维数组的几种写法</div><div>//写法1：先声明，然后new申请空间，最后赋值</div><div>　　class numthree</div><div>　　{</div><div>　　public static void main(String[] args)</div><div>　　{</div><div>　　float[][] numthree; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //定义一个float类型的2维数组</div><div>　　numthree=new float[5][5]; &nbsp; &nbsp; &nbsp; //为它分配5行5列的空间大小</div><div>　　numthree[0][0]=1.1f; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//通过下标索引去访问 &nbsp; &nbsp; 1行1列=1.1</div><div>　　numthree[1][0]=1.2f; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 2行1列=1.2</div><div>　　numthree[2][0]=1.3f; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 3行1列=1.3</div><div>　　numthree[3][0]=1.4f; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 4行1列=1.4</div><div>　　numthree[4][0]=1.5f; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 5行1列=1.5</div><div>　　System.out.println(numthree[0][0]); //打印换行输出喽</div><div>　　System.out.println(numthree[1][0]);</div><div>　　System.out.println(numthree[2][0]);</div><div>　　System.out.println(numthree[3][0]);</div><div>　　System.out.println(numthree[4][0]);</div><div>　　}</div><div>　　}</div><div>&nbsp;</div><div>//写法2：定义的同时分配空间大小</div><div>　　class numfour</div><div>　　{</div><div>　　public static void main(String[] args)</div><div>　　{</div><div>　　short[][] numfour=new short[5][8]; //定义一个short类型的数组同时为它分配5行8列的空间大小</div><div>　　numfour[0][7]=10;</div><div>　　numfour[1][6]=20;</div><div>　　numfour[2][5]=30;</div><div>　　numfour[3][4]=40;</div><div>　　numfour[4][3]=50;</div><div>　　System.out.println(numfour[0][7]);</div><div>　　System.out.println(numfour[1][6]);</div><div>　　System.out.println(numfour[2][5]);</div><div>　　System.out.println(numfour[3][4]);</div><div>　　System.out.println(numfour[4][3]);</div><div>　　}</div><div>　　}</div><div>&nbsp;</div><div>//写法3：不规则数组</div><div>　　class numfive</div><div>　　{</div><div>　　public static void main(String[] args)</div><div>　　{</div><div>　　long[][] numfive=new long[5][]; &nbsp; &nbsp; //定义一个long类型的不规则数组</div><div>　　numfive[0]=new long[5]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //为第1行分配5列</div><div>　　numfive[1]=new long[6]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //为第2行分配6列</div><div>　　numfive[2]=new long[7]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //为第3行分配7列</div><div>　　numfive[3]=new long[8]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //为第4行分配8列</div><div>　　numfive[4]=new long[9]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //为第5行分配9列</div><div>　　numfive[0][4]=10000000000L; &nbsp; &nbsp; &nbsp; &nbsp; //1行5列=10000000000</div><div>　　numfive[1][5]=20000000000L; &nbsp; &nbsp; &nbsp; &nbsp; //2行6列=20000000000</div><div>　　numfive[2][6]=30000000000L; &nbsp; &nbsp; &nbsp; &nbsp; //3行7列=30000000000</div><div>　　numfive[3][7]=40000000000L; &nbsp; &nbsp; &nbsp; &nbsp; //4行8列=40000000000</div><div>　　numfive[4][8]=50000000000L; &nbsp; &nbsp; &nbsp; &nbsp; //5行9列=50000000000</div><div>　　System.out.println(numfive[0][4]); //打印换行输出喽</div><div>　　System.out.println(numfive[1][5]);</div><div>　　System.out.println(numfive[2][6]);</div><div>　　System.out.println(numfive[3][7]);</div><div>　　System.out.println(numfive[4][8]);</div><div>　　System.out.println(numfive[4][7]); //打印输出一个没有定义数组元素的数组 java会自动将他初始化值为0</div><div>　　}</div><div>　　}</div><div>&nbsp;</div><div>//写法4：定义的同时赋初始值</div><div>　　class numsix</div><div>　　{</div><div>　　public static void main(String[] args)</div><div>　　{</div><div>　　double[][] numsix={{1.111D,2.222D,3.333D},{4.444D,5.555D,6.666D}}; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //定义double型的数组分配3行3列的空间同时赋值</div><div>　　System.out.println(numsix[0][0]); //打印换行输出1行1列=1.111</div><div>　　System.out.println(numsix[1][1]); //打印换行输出2行2列=5.555</div><div>　　}</div><div>　　}</div><div>&nbsp;</div><div>//写法5：定义不规则的2维数组同时赋初始值</div><div>　　class numseven</div><div>　　{</div><div>　　public static void main(String[] args)</div><div>　　{</div><div>　　int[][] numseven=new int[][]{{10,20,30},{40,50},{60}}; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//没什么好说的如果你在看不懂 那就别学了！</div><div>　　System.out.println(numseven[0][2]);</div><div>　　System.out.println(numseven[1][1]);</div><div>　　System.out.println(numseven[0][0]);</div><div>　　}</div><div>　　}</div><div>&nbsp;</div><div>//写法6：定义不规则的2维数组同时赋初始值</div><div>　　class numeight</div><div>　　{</div><div>　　public static void main(String[] args)</div><div>　　{</div><div>　　int[][] numeight={{100,200,300,400},{500,600,700,800},{900,1000,1100,1200,1300}};</div><div>　　System.out.println(numeight[0][2]);</div><div>　　System.out.println(numeight[1][2]);</div><div>　　System.out.println(numeight[2][1]);</div><div>　　}</div><div>　　}</div></div><img src ="http://www.blogjava.net/jjshcc/aggbug/408417.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-03 11:16 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/03/408417.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>谈java的import</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/03/408414.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Fri, 03 Jan 2014 02:25:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/03/408414.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408414.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/03/408414.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408414.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408414.html</trackback:ping><description><![CDATA[<div><span style="font-family: 'Times New Roman'; line-height: 23px; "><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">程序员可以使用两种import语句：</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　单类型导入(single-type-import)，例如import java.io.File;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　按需类型导入(type-import-on-demand)，例如 import java.io.*;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　关于这两种导入类型大家各有所爱，众说纷纭。这里分析一下这两种导入类型的大致工作原理供大家参考。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　单类型导入比较好理解，仅仅导入一个public类或者接口。而对于按需类型导入，有人误解为导入一个包下的所有类，其实不然，看名字就知道，他只会按需导入，也就是说它并非导入整个包，而仅仅导入当前类需要使用的类。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　既然如此是不是就可以放心的使用按需类型导入呢?非也，非也。因为单类型导入和按需类型导入对类文件的定位算法是不一样的。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　java编译器会从启动目录(bootstrap)，扩展目录(extension)和用户类路径下去定位需要导入的类，而这些目录仅仅是给出了类的顶层目录。编译器的类文件定位方法大致可以理解为如下公式：</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　顶层路径名 \ 包名 \ 文件名.class = 绝对路径</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　对于单类型导入很简单，因为包明和文件名都已经确定，所以可以一次性查找定位。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　对于按需类型导入则比较复杂，编译器会把包名和文件名进行排列组合，然后对所有的可能性进行类文件查找定位。例如：</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　package com;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　import java.io.*;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　import java.util.*;</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　当你的类文件中用到了File类，那么可能出现File类的地方如下:</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　1、File \ File类属于无名包，就是说File类没有package语句，编译器会首先搜索无名包</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　2、com.File \ File类属于当前包</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　3、java.lang.File \编译器会自动导入java.lang包</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　4、java.io.File</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　5、java.util.File</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　需要注意的地方就是，编译器找到java.io.File类之后并不会停止下一步的寻找，而要把所有的可能性都查找完以确定是否有类导入冲突。假设此时的顶层路径有三个，那么编译器就会进行3*5=15次查找。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　了解以上原理之后，我们可以得出这样的结论：按需类型导入是绝对不会降低Java代码的执行效率的，但会影响到Java代码的编译速度。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　查看JDK的源代码就知道SUN的软件工程师一般不会使用按需类型导入。因为使用单类型导入至少有以下两点好处：</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　1。提高编译速度。</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　2。避免命名冲突。(例如：当你import java.awt.*;import java.util.*后，使用List的时候编译器将会出编译错误)</p><p style="margin-top: 15px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 23px; font-size: 14px; ">　　当然，使用单类型导入会使用你的import语句看起来很长。</p></span></div><img src ="http://www.blogjava.net/jjshcc/aggbug/408414.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-03 10:25 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/03/408414.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Thread.start()与Thread.run()有什么区别？</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/03/408413.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Fri, 03 Jan 2014 02:18:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/03/408413.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408413.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/03/408413.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408413.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408413.html</trackback:ping><description><![CDATA[<div><div>Thread.start()与Thread.run()有什么区别？</div><div></div><div>run()方法，用于封装线程运行的任务代码。直接用创建的线程对象调用，<span style="color: red; "><strong>并没有产生新的线程</strong></span>，仅仅是当前正在运行的线程(如，主线程)在执行run方法.</div><div></div><div>start()方法，<span style="color: red; "><strong>共有两个作用，1，开启了当前线程</strong></span>，也就是说，当前程序<span style="color: red; "><strong>又多了一条执行路径</strong></span>和当前线程(主线程)并发执行。而run()方法会被新开启的线程运行。<span style="color: red; "><strong>2，调用线程的run（）方法。</strong></span></div></div><img src ="http://www.blogjava.net/jjshcc/aggbug/408413.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-03 10:18 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/03/408413.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中ArrayList和LinkedList区别</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/03/408412.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Fri, 03 Jan 2014 02:12:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/03/408412.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408412.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/03/408412.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408412.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408412.html</trackback:ping><description><![CDATA[<div><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; ">
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">一般大家都知道ArrayList和LinkedList的大致区别：&nbsp;<br />
<span style="font-size: small; line-height: 1.5em; ">&nbsp;&nbsp;&nbsp;&nbsp; 1.ArrayList是实现了基于动态数组的数据结构，LinkedList基于链表的数据结构。</span>&nbsp;<br />
<span style="font-size: small; line-height: 1.5em; ">&nbsp;&nbsp;&nbsp;&nbsp; 2.对于随机访问get和set，ArrayList觉得优于LinkedList，因为LinkedList要移动指针。</span>&nbsp;<br />
<span style="font-size: small; line-height: 1.5em; ">&nbsp;&nbsp;&nbsp;&nbsp; 3.对于新增和删除操作add和remove，LinedList比较占优势，因为ArrayList要移动数据。</span>&nbsp;<br />
<br />
<span style="font-size: small; line-height: 1.5em; ">ArrayList和LinkedList是两个集合类，用于存储一系列的对象引用(references)。例如我们可以用ArrayList来存储一系列的String或者Integer。那么ArrayList和LinkedList在性能上有什么差别呢？什么时候应该用ArrayList什么时候又该用LinkedList呢？</span></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br />
<span style="font-size: small; line-height: 1.5em; "><strong style="font-weight: bold; ">一．时间复杂度</strong></span>&nbsp;<br />
<span style="font-size: small; line-height: 1.5em; ">首先一点关键的是，ArrayList的内部实现是基于基础的对象数组的，因此，它使用get方法访问列表中的任意一个元素时(random access)，它的速度要比LinkedList快。LinkedList中的get方法是按照顺序从列表的一端开始检查，直到另外一端。对LinkedList而言，访问列表中的某个指定元素没有更快的方法了。</span>&nbsp;<br />
<span style="font-size: small; line-height: 1.5em; ">假设我们有一个很大的列表，它里面的元素已经排好序了，这个列表可能是ArrayList类型的也可能是LinkedList类型的，现在我们对这个列表来进行二分查找(binary search)，比较列表是ArrayList和LinkedList时的查询速度，看下面的程序：</span>&nbsp;<br />
</p>
<div><span style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; font-size: 12px; ">
<ol start="1" style="font-size: 1em; line-height: 1.4em; margin-top: 0px; margin-right: 0px; margin-bottom: 1px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #d1d7dc; border-right-color: #d1d7dc; border-bottom-color: #d1d7dc; border-left-color: #d1d7dc; list-style-type: decimal; list-style-position: initial; list-style-image: initial; background-color: #ffffff; color: #2b91af; ">
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">package</span><span style="color: black; ">&nbsp;com.mangocity.test;&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">import</span><span style="color: black; ">&nbsp;java.util.LinkedList;&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">import</span><span style="color: black; ">&nbsp;java.util.List;&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">import</span><span style="color: black; ">&nbsp;java.util.Random;&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">import</span><span style="color: black; ">&nbsp;java.util.ArrayList;&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">import</span><span style="color: black; ">&nbsp;java.util.Arrays;&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">import</span><span style="color: black; ">&nbsp;java.util.Collections;&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">public</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">class</span><span style="color: black; ">&nbsp;TestList&nbsp;...{&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">public</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">static</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">final</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">int</span><span style="color: black; ">&nbsp;N=</span><span style="color: #c00000; ">50000</span><span style="color: black; ">;&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">public</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">static</span><span style="color: black; ">&nbsp;List&nbsp;values;&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">static</span><span style="color: black; ">...{&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Integer&nbsp;vals[]=<span style="color: #7f0055; font-weight: bold; ">new</span><span style="color: black; ">&nbsp;Integer[N];&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Random&nbsp;r=<span style="color: #7f0055; font-weight: bold; ">new</span><span style="color: black; ">&nbsp;Random();&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">for</span><span style="color: black; ">(</span><span style="color: #7f0055; font-weight: bold; ">int</span><span style="color: black; ">&nbsp;i=</span><span style="color: #c00000; ">0</span><span style="color: black; ">,currval=</span><span style="color: #c00000; ">0</span><span style="color: black; ">;i&lt;N;i++)...{&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vals=<span style="color: #7f0055; font-weight: bold; ">new</span><span style="color: black; ">&nbsp;Integer(currval);&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;currval+=r.nextInt(<span style="color: #c00000; ">100</span><span style="color: black; ">)+</span><span style="color: #c00000; ">1</span><span style="color: black; ">;&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;values=Arrays.asList(vals);&nbsp;&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">static</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">long</span><span style="color: black; ">&nbsp;timeList(List&nbsp;lst)...{&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">long</span><span style="color: black; ">&nbsp;start=System.currentTimeMillis();&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">for</span><span style="color: black; ">(</span><span style="color: #7f0055; font-weight: bold; ">int</span><span style="color: black; ">&nbsp;i=</span><span style="color: #c00000; ">0</span><span style="color: black; ">;i&lt;N;i++)...{&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">int</span><span style="color: black; ">&nbsp;index=Collections.binarySearch(lst,&nbsp;values.get(i));&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">if</span><span style="color: black; ">(index!=i)&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span style="color: blue; ">"***错误***"</span><span style="color: black; ">);&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">return</span><span style="color: black; ">&nbsp;System.currentTimeMillis()-start;&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">public</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">static</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">void</span><span style="color: black; ">&nbsp;main(String&nbsp;args[])...{&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span style="color: blue; ">"ArrayList消耗时间："</span><span style="color: black; ">+timeList(</span><span style="color: #7f0055; font-weight: bold; ">new</span><span style="color: black; ">&nbsp;ArrayList(values)));&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span style="color: blue; ">"LinkedList消耗时间："</span><span style="color: black; ">+timeList(</span><span style="color: #7f0055; font-weight: bold; ">new</span><span style="color: black; ">&nbsp;LinkedList(values)));&nbsp;&nbsp;&nbsp;</span></span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</span></li>
     <li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">} &nbsp;&nbsp;</span></li>
</ol>
</span></div>
<p>&nbsp;</p>
</span></div>
<div><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; "><span style="font-size: small; line-height: 1.5em; ">我得到的输出是：ArrayList消耗时间：15&nbsp;</span><br />
<span style="font-size: small; line-height: 1.5em; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LinkedList消耗时间：2596&nbsp;</span><br />
<span style="font-size: small; line-height: 1.5em; ">这个结果不是固定的，但是基本上ArrayList的时间要明显小于LinkedList的时间。因此在这种情况下不宜用LinkedList。二分查找法使用的随机访问(random access)策略，而LinkedList是不支持快速的随机访问的。对一个LinkedList做随机访问所消耗的时间与这个list的大小是成比例的。而相应的，在ArrayList中进行随机访问所消耗的时间是固定的。&nbsp;</span><br />
<span style="font-size: small; line-height: 1.5em; ">这是否表明ArrayList总是比LinkedList性能要好呢？这并不一定，在某些情况下LinkedList的表现要优于ArrayList，有些算法在LinkedList中实现时效率更高。比方说，利用Collections.reverse方法对列表进行反转时，其性能就要好些。&nbsp;</span><br />
<span style="font-size: small; line-height: 1.5em; "><span style="font-size: small; line-height: 1.5em; ">看这样一个例子，加入我们有一个列表，要对其进行大量的插入和删除操作，在这种情况下LinkedList就是一个较好的选择。请看如下一个极端的例子，我们重复的在一个列表的开端插入一个元素：</span>&nbsp;<br />
</span></span></div>
<div><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; "><div id="" style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; font-size: 12px; background-color: transparent; width: 679px; overflow-x: auto; overflow-y: auto; margin-left: 9px; padding-top: 1px; padding-right: 1px; padding-bottom: 1px; padding-left: 1px; word-break: break-all; word-wrap: break-word; "><div><div style="padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; text-align: left; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: black; font-weight: bold; ">Java代码&nbsp;<embed wmode="transparent" src="http://pengcqu.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" width="14" height="15" flashvars="clipboard=package%20com.mangocity.test%3B%20%0A%0Aimport%20java.util.*%3B%20%0Apublic%20class%20ListDemo%20%7B%20%0A%20%20%20%20%20static%20final%20int%20N%3D50000%3B%20%0A%20%20%20%20%20static%20long%20timeList(List%20list)%7B%20%0A%20%20%20%20%20long%20start%3DSystem.currentTimeMillis()%3B%20%0A%20%20%20%20%20Object%20o%20%3D%20new%20Object()%3B%20%0A%20%20%20%20%20for(int%20i%3D0%3Bi%3CN%3Bi%2B%2B)%20%0A%20%20%20%20%20%20%20%20%20list.add(0%2C%20o)%3B%20%0A%20%20%20%20%20return%20System.currentTimeMillis()-start%3B%20%0A%20%20%20%20%20%7D%20%0A%20%20%20%20%20public%20static%20void%20main(String%5B%5D%20args)%20%7B%20%0A%20%20%20%20%20%20%20%20%20System.out.println(%22ArrayList%E8%80%97%E6%97%B6%EF%BC%9A%22%2BtimeList(new%20ArrayList()))%3B%20%0A%20%20%20%20%20%20%20%20%20System.out.println(%22LinkedList%E8%80%97%E6%97%B6%EF%BC%9A%22%2BtimeList(new%20LinkedList()))%3B%20%0A%20%20%20%20%20%7D%20%0A%7D%20%0A" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">&nbsp;<a href="http://pengcqu.iteye.com/blog/502676" title="收藏这段代码" style="color: #e9650e; text-decoration: underline; "><img src="http://pengcqu.iteye.com/images/icon_star.png" alt="收藏代码" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; " /></a></div></div><ol start="1" style="font-size: 1em; line-height: 1.4em; margin-top: 0px; margin-right: 0px; margin-bottom: 1px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #d1d7dc; border-right-color: #d1d7dc; border-bottom-color: #d1d7dc; border-left-color: #d1d7dc; list-style-type: decimal; list-style-position: initial; list-style-image: initial; background-color: #ffffff; color: #2b91af; "><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">package</span><span style="color: black; ">&nbsp;com.mangocity.test;&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;</span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">import</span><span style="color: black; ">&nbsp;java.util.*;&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">public</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">class</span><span style="color: black; ">&nbsp;ListDemo&nbsp;{&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">static</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">final</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">int</span><span style="color: black; ">&nbsp;N=</span><span style="color: #c00000; ">50000</span><span style="color: black; ">;&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">static</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">long</span><span style="color: black; ">&nbsp;timeList(List&nbsp;list){&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">long</span><span style="color: black; ">&nbsp;start=System.currentTimeMillis();&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;o&nbsp;=&nbsp;<span style="color: #7f0055; font-weight: bold; ">new</span><span style="color: black; ">&nbsp;Object();&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">for</span><span style="color: black; ">(</span><span style="color: #7f0055; font-weight: bold; ">int</span><span style="color: black; ">&nbsp;i=</span><span style="color: #c00000; ">0</span><span style="color: black; ">;i&lt;N;i++)&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add(<span style="color: #c00000; ">0</span><span style="color: black; ">,&nbsp;o);&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">return</span><span style="color: black; ">&nbsp;System.currentTimeMillis()-start;&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #7f0055; font-weight: bold; ">public</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">static</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">void</span><span style="color: black; ">&nbsp;main(String[]&nbsp;args)&nbsp;{&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span style="color: blue; ">"ArrayList耗时："</span><span style="color: black; ">+timeList(</span><span style="color: #7f0055; font-weight: bold; ">new</span><span style="color: black; ">&nbsp;ArrayList()));&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span style="color: blue; ">"LinkedList耗时："</span><span style="color: black; ">+timeList(</span><span style="color: #7f0055; font-weight: bold; ">new</span><span style="color: black; ">&nbsp;LinkedList()));&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">}&nbsp;&nbsp;&nbsp;</span></li></ol></div><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;这时我的输出结果是：ArrayList耗时：2463</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br /><span style="font-size: small; line-height: 1.5em; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LinkedList耗时：15</span>&nbsp;<br /><span style="font-size: small; line-height: 1.5em; ">这和前面一个例子的结果截然相反，当一个元素被加到ArrayList的最开端时，所有已经存在的元素都会后移，这就意味着数据移动和复制上的开销。相反的，将一个元素加到LinkedList的最开端只是简单的未这个元素分配一个记录，然后调整两个连接。在LinkedList的开端增加一个元素的开销是固定的，而在ArrayList的开端增加一个元素的开销是与ArrayList的大小成比例的。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br /><span style="font-size: small; line-height: 1.5em; "><strong style="font-weight: bold; ">二．空间复杂度</strong></span>&nbsp;<br /><span style="font-size: small; line-height: 1.5em; ">在LinkedList中有一个私有的内部类，定义如下：</span></p><div id="" style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Consolas, 'Courier New', monospace; font-size: 12px; background-color: transparent; width: 679px; overflow-x: auto; overflow-y: auto; margin-left: 9px; padding-top: 1px; padding-right: 1px; padding-bottom: 1px; padding-left: 1px; word-break: break-all; word-wrap: break-word; "><div><div style="padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; text-align: left; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: black; font-weight: bold; ">Java代码&nbsp;<embed wmode="transparent" src="http://pengcqu.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" width="14" height="15" flashvars="clipboard=private%20static%20class%20Entry%20%7B%20%0A%20%20%20%20%20%20%20%20%20Object%20element%3B%20%0A%20%20%20%20%20%20%20%20%20Entry%20next%3B%20%0A%20%20%20%20%20%20%20%20%20Entry%20previous%3B%20%0A%20%20%20%20%20%7D%20" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer">&nbsp;<a href="http://pengcqu.iteye.com/blog/502676" title="收藏这段代码" style="color: #e9650e; text-decoration: underline; "><img src="http://pengcqu.iteye.com/images/icon_star.png" alt="收藏代码" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; " /></a></div></div><ol start="1" style="font-size: 1em; line-height: 1.4em; margin-top: 0px; margin-right: 0px; margin-bottom: 1px; margin-left: 0px; padding-top: 2px; padding-right: 0px; padding-bottom: 2px; padding-left: 0px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #d1d7dc; border-right-color: #d1d7dc; border-bottom-color: #d1d7dc; border-left-color: #d1d7dc; list-style-type: decimal; list-style-position: initial; list-style-image: initial; background-color: #ffffff; color: #2b91af; "><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; "><span style="color: #7f0055; font-weight: bold; ">private</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">static</span>&nbsp;<span style="color: #7f0055; font-weight: bold; ">class</span><span style="color: black; ">&nbsp;Entry&nbsp;{&nbsp;&nbsp;&nbsp;</span></span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;element;&nbsp;&nbsp;&nbsp;</span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Entry&nbsp;next;&nbsp;&nbsp;&nbsp;</span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Entry&nbsp;previous;&nbsp;&nbsp;&nbsp;</span></li><li style="font-size: 1em; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 38px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 10px; border-left-width: 1px; border-left-style: solid; border-left-color: #d1d7dc; background-color: #fafafa; line-height: 18px; "><span style="color: black; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</span></li></ol></div><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br /><span style="font-size: small; line-height: 1.5em; ">每个Entry对象reference列表中的一个元素，同时还有在LinkedList中它的上一个元素和下一个元素。一个有1000个元素的LinkedList对象将有1000个链接在一起的Entry对象，每个对象都对应于列表中的一个元素。这样的话，在一个LinkedList结构中将有一个很大的空间开销，因为它要存储这1000个Entity对象的相关信息。</span>&nbsp;<br /><span style="font-size: small; line-height: 1.5em; ">ArrayList使用一个内置的数组来存储元素，这个数组的起始容量是10.当数组需要增长时，新的容量按如下公式获得：新容量=(旧容量*3)/2+1，也就是说每一次容量大概会增长50%。这就意味着，如果你有一个包含大量元素的ArrayList对象，那么最终将有很大的空间会被浪费掉，这个浪费是由ArrayList的工作方式本身造成的。如果没有足够的空间来存放新的元素，数组将不得不被重新进行分配以便能够增加新的元素。对数组进行重新分配，将会导致性能急剧下降。如果我们知道一个ArrayList将会有多少个元素，我们可以通过构造方法来指定容量。我们还可以通过trimToSize方法在ArrayList分配完毕之后去掉浪费掉的空间。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br /><span style="font-size: small; line-height: 1.5em; ">三．总结</span>&nbsp;<br /><span style="font-size: small; line-height: 1.5em; ">ArrayList和LinkedList在性能上各有优缺点，都有各自所适用的地方，总的说来可以描述如下：</span>&nbsp;<br /><span style="font-size: small; line-height: 1.5em; ">1．对ArrayList和LinkedList而言，在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言，主要是在内部数组中增加一项，指向所添加的元素，偶尔可能会导致对数组重新进行分配；而对LinkedList而言，这个开销是统一的，分配一个内部Entry对象。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br /><span style="font-size: small; line-height: 1.5em; ">2．在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动；而在LinkedList的中间插入或删除一个元素的开销是固定的。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br /><span style="font-size: small; line-height: 1.5em; ">3．LinkedList不支持高效的随机元素访问。</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br /><span style="font-size: small; line-height: 1.5em; ">4．ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间，而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间</span></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><br /><span style="font-size: small; line-height: 1.5em; ">可以这样说：</span><span style="font-size: small; line-height: 1.5em; color: red; "><strong>当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会提供比较好的性能；当你的操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。</strong></span></p></span></div><img src ="http://www.blogjava.net/jjshcc/aggbug/408412.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-03 10:12 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/03/408412.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 默认访问权限</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/03/408411.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Fri, 03 Jan 2014 01:56:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/03/408411.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408411.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/03/408411.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408411.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408411.html</trackback:ping><description><![CDATA[<div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: red; "><strong>&nbsp;如果一个类的成员没有任何权限修饰，那么它门就是缺省包访问权</strong></span><span style="color: red; "><strong>限，用friendly来表示，注</strong></span><span style="color: red; "><strong>意friendly不是Java中的关键字，这里是个人喜欢的方式用它表示而已，有人喜欢说是default或者是pacakge，只是帮助理解</strong></span>。同一个包内其它类可以访问，但包外就不可以。对于同一个文件夹下的、没有用package的classes，Java会自动将这些classes初见为隶属于该目录的default package，可以相互调用class中的friendly成员。如以下两个class分别在同一个文件夹的两个文件中，虽然没有引入package，但隶属于相同的default package。</div><div>　　 class Sundae{</div><div>　　 //以下两个方法缺省为friendly</div><div>　　 Sundae(){}</div><div>　　 Void f() {System.out.println(&#8220;Sundae.f()&#8221;);</div><div>　　 }</div><div>　　 public class IceCream{</div><div>　　 public static void main(String[] args){</div><div>　　 Sundae x = new Sundae();</div><div>　　 x.f();</div><div>　　 }</div><div>　　 }</div><div>对于类来说：同一个包中的类可以用。总之，类只可以声明为public或者friendly。</div></div><img src ="http://www.blogjava.net/jjshcc/aggbug/408411.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-03 09:56 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/03/408411.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML解析器SAX，DOM，JDOM，JAXP的优缺点</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/02/408394.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Thu, 02 Jan 2014 08:12:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/02/408394.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408394.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/02/408394.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408394.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408394.html</trackback:ping><description><![CDATA[<div><div><span style="color: red; "><strong>DOM 构建整个文档驻留内存的树。如果文档很大，就会要求有极大的内存。</strong></span></div><div>DOM 创建表示原始文档中每个东西的对象，包括元素、文本、属性和空格。如果您只需关注原始文档的一小部分，那么创建那些永远不被使用的对象是极其浪费的。</div><div><span style="color: red; "><strong>DOM 解析器必须在您的代码取得控制权之前读取整个文档。对于非常大的文档，这会引起显著的延迟。</strong></span></div><div>SAX 解析器向您的代码发送事件。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时，它会告诉您。您可以决定什么事件对您重要，而且可以决定要创建什么类型的数据结构以保存来自这些事件的数据。如果您没有显式地保存来自某个事件的数据，它就被丢弃。</div><div>SAX 解析器根本不创建任何对象，它只是将事件传递给您的应用程序。如果希望基于那些事件创建对象，这将由您来完成。</div><div>SAX 解析器在解析开始的时候就开始发送事件。当解析器发现文档开始、元素开始和文本等时，代码会收到一个事件。您的应用程序可以立即开始生成结果；您不必一直等到整个文档被解析完毕。更妙的是，如果您只查找文档中某些内容，代码一旦找到所要找的东西就可以抛出一个异常。该异常会停止 SAX 解析器，然后代码用它找到的数据做它需要做的任何事。</div><div>SAX 事件是无状态的。当 SAX 解析器在 XML 文档中发现文本时，它就向您的代码发送一个事件。该事件仅仅给您发现的文本；它不告诉您什么元素包含那个文本。如果您想知道这一点，则必须自己编写状态管理代码。</div><div>SAX 事件不是持久的。如果应用程序需要一个数据结构来对 XML 文档建模，则必须自己编写那样的代码。如果您需要从 SAX 事件访问数据，并且没有把那个数据存储在代码中，那么您不得不再次解析该文档。</div><div>SAX 不是由一个集中管理的组织控制的。尽管到目前为止这还没有引起什么问题，但如果 SAX 是由象 W3C 这样的一个组织控制的话，有些开发人员会感觉更自在。</div><div><span style="color: red; "><strong>JDOM 的主要特性是它极大地减少了您必须编写的代码数量。JDOM 应用程序的长度通常是 DOM 应用程序的三分之一，大约是 SAX 应用程序的一半。</strong></span></div><div><span style="color: red; "><strong>JAXP为使用 DOM、SAX 和 XSLT 处理 XML 文档提供公共接口</strong></span><br /><br /><div><span style="color: red; "><strong>综述：SAX在对速度要求特别快，或机器内存不足的情况下使用；DOM在对解析速度要求不高，或xml文档不是很大的情况下使用；对于频繁修改xml文件内容的情况，建议用dom，因为sax每次都要从头到尾遍历节点，而且不易实现。虽然SAX表现较好，这要依赖于它特定的解析方式，一个 SAX 检测即将到来的XML流，但并没有载入到内存（当然当XML流被读入时，会有部分文档暂时隐藏在内存中）。</strong></span></div></div></div><div></div><img src ="http://www.blogjava.net/jjshcc/aggbug/408394.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-02 16:12 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/02/408394.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ARRAYLIST VECTOR LINKEDLIST 区别与用法</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/02/408393.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Thu, 02 Jan 2014 08:03:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/02/408393.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408393.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/02/408393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408393.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408393.html</trackback:ping><description><![CDATA[<div>&nbsp;&nbsp; &nbsp; &nbsp;ArrayList 和Vector是采用数组方式存储数据，此数组元素数大于实际存储的数据以便增加和插入元素，<span style="color: red; "><strong>都允许直接序号索引元素</strong></span>，但是插入数据要设计到数组元素移动等内存操作，所以索引数据快插入数据慢，<span style="color: red; "><strong>Vector由于使用了synchronized方法（线程安全）所以性能上比ArrayList要差</strong></span>，<span style="color: red; "><strong>LinkedList使用双向链表实现存储，按序号索引数据需要进行向前或向后遍历，但是插入数据时只需要记录本项的前后项即可，所以插入数度较快！</strong></span></div><img src ="http://www.blogjava.net/jjshcc/aggbug/408393.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-02 16:03 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/02/408393.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中HashMap,LinkedHashMap,TreeMap的区别</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/02/408392.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Thu, 02 Jan 2014 07:56:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/02/408392.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408392.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/02/408392.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408392.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408392.html</trackback:ping><description><![CDATA[<div><div>java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap</div><div><br />Map主要用于存储健值对，根据键得到值，因此不允许键重复(重复了覆盖了),但允许值重复。<br /></div><div>Hashmap 是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值，具有很快的访问速度，遍历时，取得数据的顺序是完全随机的。HashMap<span style="color: red; "><strong>最多只允许一条记录的键为Null</strong></span>;允许多条记录的值为 Null;<span style="color: red; "><strong>HashMap不支持线程的同步</strong></span>，即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步，<span style="color: red; "><strong>可以用 Collections的synchronizedMap方法使HashMap具有同步的能力，或者使用ConcurrentHashMap。<br /><br /></strong></span></div><div>Hashtable与 HashMap类似,它继承自Dictionary类，不同的是:<span style="color: red; "><strong>它不允许记录的键或者值为空;它支持线程的同步，即任一时刻只有一个线程能写Hashtable</strong></span>,因此也导致了 Hashtable在写入时会比较慢。<br /></div><div>LinkedHashMap<span style="color: red; "><strong>保存了记录的插入顺序</strong></span>，在用Iterator遍历LinkedHashMap时，先得到的记录肯定是先插入的.也可以在构造时用带参数，按照应用次数排序。在遍历的时候会比HashMap慢，不过有种情况例外，当HashMap容量很大，实际数据较少时，遍历起来可能会比LinkedHashMap慢，因为LinkedHashMap的遍历速度只和实际数据有关，和容量无关，而HashMap的遍历速度和他的容量有关。<br /></div><div>TreeMap实现SortMap接口，能够把它<strong>保存的记录根据键排序</strong>,<strong style="color: red; ">默认是按键值的升序排序</strong>，也可以指定排序的比较器，当用Iterator 遍历TreeMap时，得到的记录是排过序的。<br /></div><div>一般情况下，我们用的最多的是HashMap,HashMap里面存入的键值对在取出的时候是随机的,它根据键的HashCode值存储数据,根据键可以直接获取它的值，具有很快的访问速度。在Map 中插入、删除和定位元素，HashMap 是最好的选择。</div><div>TreeMap取出来的是排序后的键值对。但如果您要按自然顺序或自定义顺序遍历键，那么TreeMap会更好。</div><div>LinkedHashMap 是HashMap的一个子类，如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按读取顺序来排列，像连接池中可以应用。</div></div><img src ="http://www.blogjava.net/jjshcc/aggbug/408392.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-02 15:56 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/02/408392.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>String,StringBuffer与StringBuilder的区别??</title><link>http://www.blogjava.net/jjshcc/archive/2014/01/02/408390.html</link><dc:creator>Eric_jiang</dc:creator><author>Eric_jiang</author><pubDate>Thu, 02 Jan 2014 07:48:00 GMT</pubDate><guid>http://www.blogjava.net/jjshcc/archive/2014/01/02/408390.html</guid><wfw:comment>http://www.blogjava.net/jjshcc/comments/408390.html</wfw:comment><comments>http://www.blogjava.net/jjshcc/archive/2014/01/02/408390.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jjshcc/comments/commentRss/408390.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jjshcc/services/trackbacks/408390.html</trackback:ping><description><![CDATA[<div><div>String<strong style="color: red; "> 字符串常量</strong></div><div>StringBuffer 字符串变量<span style="color: red; "><strong>（线程安全）</strong></span></div><div>StringBuilder 字符串变量<span style="color: red; "><strong>（非线程安全）<br /><br /></strong></span></div><div>&nbsp;&nbsp; &nbsp; &nbsp;简要的说， String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象，然后将指针指向新的 String 对象，所以经常改变内容的字符串最好不要用 String ，因为每次生成对象都会对系统性能产生影响，特别当内存中无引用对象多了以后， JVM 的 GC 就会开始工作，那速度是一定会相当慢的。</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;而如果是使用 StringBuffer 类则结果就不一样了，每次结果都会对 StringBuffer 对象本身进行操作，而不是生成新的对象，再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ，特别是字符串对象经常改变的情况下。而在某些特别情况下， String 对象的字符串拼接其实是被 JVM 解释成了 StringBuffer 对象的拼接，所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢，而特别是以下的字符串对象生成中， String 效率是远要比 StringBuffer 快的：</div><div>&nbsp;String S1 = &#8220;This is only a&#8221; + &#8220; simple&#8221; + &#8220; test&#8221;;</div><div>&nbsp;StringBuffer Sb = new StringBuilder(&#8220;This is only a&#8221;).append(&#8220; simple&#8221;).append(&#8220; test&#8221;);</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;你会很惊讶的发现，生成 String S1 对象的速度简直太快了，而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏，在 JVM 眼里，这个</div><div>&nbsp;String S1 = &#8220;This is only a&#8221; + &#8220; simple&#8221; + &#8220;test&#8221;; 其实就是：</div><div>&nbsp;String S1 = &#8220;This is only a simple test&#8221;; 所以当然不需要太多的时间了。但大家这里要注意的是，如果你的字符串是来自另外的 String 对象的话，速度就没那么快了，譬如：</div><div>String S2 = &#8220;This is only a&#8221;;</div><div>String S3 = &#8220; simple&#8221;;</div><div>String S4 = &#8220; test&#8221;;</div><div>String S1 = S2 +S3 + S4;</div><div><span>这时候 JVM 会规规矩矩的按照原来的方式去做</span><span style="color: red; "><br /><br /></span></div><div></div><div><span style="color: red; "><strong>在大部分情况下 StringBuffer &gt; String<br /><br /></strong></span></div><div>StringBuffer</div><div>&nbsp;&nbsp;&nbsp;&nbsp;Java.lang.StringBuffer线程安全的可变字符序列。一个类似于 String 的字符串缓冲区，但不能修改。虽然在任意时间点上它都包含某种特定的字符序列，但通过某些方法调用可以改变该序列的长度和内容。</div><div>&nbsp;&nbsp;&nbsp;&nbsp;可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步，因此任意特定实例上的所有操作就好像是以串行顺序发生的，该顺序与所涉及的每个线程进行的方法调用顺序一致。</div><div>&nbsp;&nbsp;&nbsp;&nbsp;StringBuffer 上的主要操作是 append 和 insert 方法，可重载这些方法，以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串，然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端；而 insert 方法则在指定的点添加字符。</div><div>例如，如果 z 引用一个当前内容是&#8220;start&#8221;的字符串缓冲区对象，则此方法调用 z.append("le") 会使字符串缓冲区包含&#8220;startle&#8221;，而 z.insert(4, "le") 将更改字符串缓冲区，使之包含&#8220;starlet&#8221;。<br /></div><div><span style="color: red; "><strong>在大部分情况下 StringBuilder &gt; StringBuffer</strong></span></div><div>java.lang.StringBuilde</div><div>java.lang.StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API，但不保证同步。该类被设计用作 StringBuffer 的一个简易替换，用在字符串缓冲区被单个线程使用的时候（这种情况很普遍）。如果可能，建议优先采用该类，因为在大多数实现中，它比 StringBuffer 要快。两者的方法基本相同。</div></div><img src ="http://www.blogjava.net/jjshcc/aggbug/408390.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jjshcc/" target="_blank">Eric_jiang</a> 2014-01-02 15:48 <a href="http://www.blogjava.net/jjshcc/archive/2014/01/02/408390.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>