﻿<?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-yqin-文章分类-设计模式</title><link>http://www.blogjava.net/yqin/category/45343.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 16 Jun 2010 05:10:12 GMT</lastBuildDate><pubDate>Wed, 16 Jun 2010 05:10:12 GMT</pubDate><ttl>60</ttl><item><title>单例模式完全解析</title><link>http://www.blogjava.net/yqin/articles/323628.html</link><dc:creator>爱运动 爱生活</dc:creator><author>爱运动 爱生活</author><pubDate>Tue, 15 Jun 2010 09:39:00 GMT</pubDate><guid>http://www.blogjava.net/yqin/articles/323628.html</guid><wfw:comment>http://www.blogjava.net/yqin/comments/323628.html</wfw:comment><comments>http://www.blogjava.net/yqin/articles/323628.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yqin/comments/commentRss/323628.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yqin/services/trackbacks/323628.html</trackback:ping><description><![CDATA[<p align="left" style="text-align:left;line-height:15.0pt;"><span style="font-size:9.0pt;font-family:宋体;color:black;">本文将探讨单例模式的各种情况，并给出相应的建议。单例模式应该是设计模式中比较简单的一个，但是在多线程并发的环境下使用却是不那么简单了。</span><span style="font-size:9.0pt;font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">首先看最原始的单例模式。</span></p>
<p align="left" style="text-align:left;line-height:15.0pt;background:#EEEEEE"><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;1</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">package</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;xylz.study.singleton;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;2</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;3</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">class</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">&nbsp;Singleton&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;4</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;5</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">private</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;Singleton&nbsp;instance&nbsp;=&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">null</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;6</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;7</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">private</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">&nbsp;Singleton()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;8</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;9</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">10</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;Singleton&nbsp;getInstance()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">11</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">if</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;(instance&nbsp;==&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">null</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">)&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">12</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance&nbsp;=&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">new</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;Singleton();<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">13</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">14</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">return</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;instance;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">15</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">16</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">17</span>&nbsp;</p>
<p align="left" style="text-align:left;line-height:15.0pt;"><span style="font-size:9.0pt;
font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">显然这个写法在单线程环境下非常好，但是多线程会导致多个实例出现，这个大家都能理解。</span><span style="font-size:9.0pt;font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">最简单的改造方式是添加一个同步锁。</span></p>
<p align="left" style="text-align:left;line-height:15.0pt;background:#EEEEEE"><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;1</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">package</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;xylz.study.singleton;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;2</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;3</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">class</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">&nbsp;SynchronizedSingleton&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;4</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;5</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">private</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;SynchronizedSingleton&nbsp;instance&nbsp;=&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">null</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;6</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;7</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">private</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">&nbsp;SynchronizedSingleton()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;8</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;9</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">10</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">synchronized</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;SynchronizedSingleton&nbsp;getInstance()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">11</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">if</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;(instance&nbsp;==&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">null</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">)&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">12</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance&nbsp;=&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">new</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;SynchronizedSingleton();<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">13</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">14</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">return</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;instance;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">15</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">16</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">17</span>&nbsp;</p>
<p align="left" style="text-align:left;line-height:15.0pt;"><span style="font-size:9.0pt;
font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">显然上面的方法避免了并发的问题，但是由于我们只是在第一次构造对象的时候才需要同步，以后就不再需要同步，所以这里不可避免的有性能开销。于是将锁去掉采用静态的属性来解决同步锁的问题。</span></p>
<p align="left" style="text-align:left;line-height:15.0pt;background:#EEEEEE"><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;1</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">package</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;xylz.study.singleton;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;2</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;3</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">class</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">&nbsp;StaticSingleton&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;4</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;5</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">private</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;StaticSingleton&nbsp;instance&nbsp;=&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">new</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;StaticSingleton();<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;6</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;7</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">private</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">&nbsp;StaticSingleton()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;8</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;9</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">10</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;StaticSingleton&nbsp;getInstance()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">11</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">return</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;instance;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">12</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">13</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">14</span>&nbsp;</p>
<p align="left" style="text-align:left;line-height:15.0pt;"><span style="font-size:9.0pt;
font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">上面的方法既没有锁又解决了性能问题，看起来已经满足需求了。但是追求</span><span style="font-size:9.0pt;font-family:Verdana;color:black;">&#8220;</span><span style="font-size:9.0pt;font-family:宋体;color:black;">完美</span><span style="font-size:9.0pt;font-family:Verdana;
color:black;">&#8221;</span><span style="font-size:9.0pt;font-family:宋体;color:black;">的程序员想延时加载对象，希望在第一次获取的时候才构造对象，于是大家非常聪明的进行改造，也即非常出名的双重检查锁机制出来了。</span></p>
<p align="left" style="text-align:left;line-height:15.0pt;background:#EEEEEE"><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;1</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">package</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;xylz.study.singleton;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;2</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;3</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">class</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">&nbsp;DoubleLockSingleton&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;4</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;5</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">private</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;DoubleLockSingleton&nbsp;instance&nbsp;=&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">null</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;6</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;7</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">private</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">&nbsp;DoubleLockSingleton()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;8</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;9</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">10</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;DoubleLockSingleton&nbsp;getInstance()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">11</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">if</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;(instance&nbsp;==&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">null</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">)&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">12</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">synchronized</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;(DoubleLockSingleton.</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">class</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">)&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">13</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">if</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;(instance&nbsp;==&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">null</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">)&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">14</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance&nbsp;=&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">new</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;DoubleLockSingleton();<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">15</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">16</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">17</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">18</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">return</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;instance;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">19</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">20</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">21</span>&nbsp;</p>
<p align="left" style="text-align:left;line-height:15.0pt;"><span style="font-size:9.0pt;
font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">双重锁机制看起来非常巧妙的避免了上面的问题。但是真的是这样的吗？文章《</span><span style="font-size:9.0pt;font-family:Verdana;color:black;"><a href="http://www.ibm.com/developerworks/cn/java/j-dcl.html" target="_blank"><strong><span style="font-family:宋体;color:#56B6E9;text-decoration:none;text-underline:none">双重检查锁定及单例模式</span></strong></a></span><span style="font-size:9.0pt;font-family:宋体;color:black;">》中谈到了非常多演变的双重锁机制带来的问题，包括比较难以理解的指令重排序机制等。总之就是双重检查锁机制仍然对导致错误问题而不是性能问题。</span><span style="font-size:9.0pt;font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">于是继续改造，某个牛人利用</span><span style="font-size:9.0pt;font-family:Verdana;color:black;">JVM</span><span style="font-size:9.0pt;font-family:宋体;color:black;">的特性来解决上述问题，具体哪个牛人我忘记了，但是不是下面文章的作者。</span><span style="font-size:9.0pt;font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">（</span><span style="font-size:
9.0pt;font-family:Verdana;
color:black;">1</span><span style="font-size:9.0pt;font-family:宋体;color:black;">）《</span><span style="font-size:9.0pt;
font-family:Verdana;color:black;"><a href="http://www.ibm.com/developerworks/java/library/j-jtp03304/" target="_blank"><strong><span style="color:#56B6E9;text-decoration:none;text-underline:
none">Java theory and practice: Fixing the Java Memory Model, Part 2</span></strong></a></span><span style="font-size:9.0pt;font-family:宋体;color:black;">》</span><span style="font-size:9.0pt;
font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">（</span><span style="font-size:
9.0pt;font-family:Verdana;
color:black;">2</span><span style="font-size:9.0pt;font-family:宋体;color:black;">）《</span><span style="font-size:9.0pt;
font-family:Verdana;color:black;"><a href="http://www.theserverside.com/discussions/thread.tss?thread_id=35349" target="_blank"><strong><span style="color:#56B6E9;text-decoration:none;text-underline:
none">Initialize-On-Demand Holder Class and Singletons</span></strong></a></span><span style="font-size:9.0pt;font-family:宋体;color:black;">》</span></p>
<p align="left" style="text-align:left;line-height:15.0pt;background:#EEEEEE"><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;1</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">package</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;xylz.study.singleton;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;2</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;3</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">class</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">&nbsp;HolderSingleton&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;4</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;5</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">private</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">class</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingletonHolder&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;6</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;7</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingleton&nbsp;instance&nbsp;=&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">new</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingleton();<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;8</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;9</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">10</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">private</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingleton()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">11</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:green;">//maybe&nbsp;throw&nbsp;an&nbsp;Exception&nbsp;when&nbsp;doing&nbsp;something&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">12</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">13</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">14</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingleton&nbsp;getInstance()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">15</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">return</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingletonHolder.instance;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">16</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">17</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">18</span>&nbsp;</p>
<p align="left" style="text-align:left;line-height:15.0pt;"><span style="font-size:9.0pt;
font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">上述代码看起来解决了上面单例模式遇到的所有问题，而且实际上工作的很好，没有什么问题。但是却有一个致命的问题，如果第</span><span style="font-size:9.0pt;font-family:Verdana;color:black;">11</span><span style="font-size:9.0pt;font-family:宋体;color:black;">行抛出了一个异常，也就是第一次构造函数失败将导致永远无法再次得到构建对象的机会。</span><span style="font-size:9.0pt;font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">使用下面的代码测试下。</span></p>
<p align="left" style="text-align:left;line-height:15.0pt;background:#EEEEEE"><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;1</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">package</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;xylz.study.singleton;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;2</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;3</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">class</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">&nbsp;HolderSingletonTest&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;4</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;5</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">private</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">class</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingletonHolder&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;6</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;7</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingletonTest&nbsp;instance&nbsp;=&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">new</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingletonTest();<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;8</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;9</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">10</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">private</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">boolean</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;init&nbsp;=&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">false</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">11</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">12</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">private</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingletonTest()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">13</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:green;">//maybe&nbsp;throw&nbsp;an&nbsp;Exception&nbsp;when&nbsp;doing&nbsp;something&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">14</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">if</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">(!init)&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">15</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init=</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">true</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">16</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">throw</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">new</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;RuntimeException("fail");<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">17</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">18</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">19</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">20</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingletonTest&nbsp;getInstance()&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">21</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">return</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;HolderSingletonHolder.instance;<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">22</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">23</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:
10.0pt;font-family:Verdana;color:blue;">public</span>&nbsp;<span style="font-size:10.0pt;font-family:Verdana;color:blue;">static</span>&nbsp;<span style="font-size:10.0pt;
font-family:Verdana;color:blue;">void</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">24</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">for</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">(</span><span style="font-size:10.0pt;
font-family:Verdana;color:blue;">int</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;i=0;i&lt;3;i++)&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">25</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">try</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">26</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(HolderSingletonTest.getInstance());<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">27</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">catch</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;(Exception&nbsp;e)&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">28</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println("one-&gt;"+i);<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">29</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">30</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">catch</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">(ExceptionInInitializerError&nbsp;err)&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">31</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println("two-&gt;"+i);<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">32</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err.printStackTrace();<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">33</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">catch</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">(Throwable&nbsp;t)&nbsp;{<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">34</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println("three-&gt;"+i);<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">35</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.printStackTrace();<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">36</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">37</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">38</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">39</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;}<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">40</span>&nbsp;</p>
<p align="left" style="text-align:left;line-height:15.0pt;"><span style="font-size:9.0pt;font-family:宋体;color:black;">很不幸将得到以下输出：</span></p>
<p align="left" style="text-align:left;line-height:15.0pt;background:#EEEEEE"><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;1</span><span style="font-size:10.0pt;
font-family:Verdana;color:black;">&nbsp;two-&gt;0<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;2</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;java.lang.ExceptionInInitializerError<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;3</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;xylz.study.singleton.HolderSingletonTest.getInstance(HolderSingletonTest.java:21)<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;4</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;xylz.study.singleton.HolderSingletonTest.main(HolderSingletonTest.java:26)<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;5</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;Caused&nbsp;by:&nbsp;java.lang.RuntimeException:&nbsp;fail<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;6</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;xylz.study.singleton.HolderSingletonTest.&lt;init&gt;(HolderSingletonTest.java:16)<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;7</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;xylz.study.singleton.HolderSingletonTest.&lt;init&gt;(HolderSingletonTest.java:12)<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;8</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;xylz.study.singleton.HolderSingletonTest$HolderSingletonHolder.&lt;clinit&gt;(HolderSingletonTest.java:7)<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">&nbsp;9</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<!--[if gte vml 1]>
<![endif]--><img border="0" width="15" height="20" src="file:///C:/DOCUME~1/Owner/LOCALS~1/Temp/msohtml1/01/clip_image001.gif" style="border-style:initial;border-color:initial;border-bottom-width:0px;
border-left-width:0px;border-right-width:0px;border-top-width:0px;font-family:
Verdana, Georgia, Arial, Helvetica, sans-serif;margin-bottom:0px;margin-left:
0px;margin-right:0px;margin-top:0px;padding-bottom:0px;padding-left:0px;
padding-right:0px;padding-top:0px" v:shapes="_x0000_i1025" alt="" />&nbsp;2&nbsp;more<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">10</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;three-&gt;1<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">11</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;java.lang.NoClassDefFoundError:&nbsp;Could&nbsp;not&nbsp;initialize&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">class</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;xylz.study.singleton.HolderSingletonTest$HolderSingletonHolder<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">12</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;xylz.study.singleton.HolderSingletonTest.getInstance(HolderSingletonTest.java:21)<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">13</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;xylz.study.singleton.HolderSingletonTest.main(HolderSingletonTest.java:26)<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">14</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;three-&gt;2<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">15</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;java.lang.NoClassDefFoundError:&nbsp;Could&nbsp;not&nbsp;initialize&nbsp;</span><span style="font-size:10.0pt;font-family:Verdana;color:blue;">class</span><span style="font-size:10.0pt;font-family:Verdana;color:black;">&nbsp;xylz.study.singleton.HolderSingletonTest$HolderSingletonHolder<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">16</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;xylz.study.singleton.HolderSingletonTest.getInstance(HolderSingletonTest.java:21)<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">17</span><span style="font-size:
10.0pt;font-family:Verdana;color:black;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at&nbsp;xylz.study.singleton.HolderSingletonTest.main(HolderSingletonTest.java:26)<br />
</span><span style="font-size:10.0pt;font-family:Verdana;color:teal;">18</span>&nbsp;</p>
<p><span style="font-size:9.0pt;font-family:Verdana;color:black;"><br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">很显然我们想着第一次加载失败第二次能够加载成功，非常不幸，</span><span style="font-size:9.0pt;font-family:Verdana;color:black;">JVM</span><span style="font-size:9.0pt;font-family:宋体;color:black;">一旦加载某个类失败将认为此类的定义有问题，将来不再加载，这样就导致我们没有机会再加载。目前看起来没有办法避免此问题。如果要使用</span><span style="font-size:9.0pt;font-family:Verdana;color:black;">JVM</span><span style="font-size:9.0pt;font-family:宋体;color:black;">的类加载特性就必须保证类加载一定正确，否则此问题将比并发和性能更严重。如果我们的类需要初始话那么就需要想其它办法避免在构造函数中完成。看起来像是又回到了老地方，难道不是么？</span><span style="font-size:9.0pt;font-family:Verdana;color:black;"><br />
<br />
</span><span style="font-size:9.0pt;font-family:宋体;color:black;">总之，结论是目前没有一个十全十美的单例模式，而大多数情况下我们只需要满足我们的需求就行，没必有特意追求最</span><span style="font-size:9.0pt;font-family:Verdana;color:black;">&#8220;</span><span style="font-size:9.0pt;font-family:宋体;color:black;">完美</span><span style="font-size:9.0pt;font-family:Verdana;
color:black;">&#8221;</span><span style="font-size:9.0pt;font-family:宋体;color:black;">解决方案。</span></p>
<img src ="http://www.blogjava.net/yqin/aggbug/323628.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yqin/" target="_blank">爱运动 爱生活</a> 2010-06-15 17:39 <a href="http://www.blogjava.net/yqin/articles/323628.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>