﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-老刘</title><link>http://www.blogjava.net/liuex/</link><description /><language>zh-cn</language><lastBuildDate>Sat, 20 Jun 2026 17:35:12 GMT</lastBuildDate><pubDate>Sat, 20 Jun 2026 17:35:12 GMT</pubDate><ttl>60</ttl><item><title>Bitwise and Bit Shift Operators</title><link>http://www.blogjava.net/liuex/articles/244455.html</link><dc:creator>Daniel Liu</dc:creator><author>Daniel Liu</author><pubDate>Thu, 04 Dec 2008 14:01:00 GMT</pubDate><guid>http://www.blogjava.net/liuex/articles/244455.html</guid><wfw:comment>http://www.blogjava.net/liuex/comments/244455.html</wfw:comment><comments>http://www.blogjava.net/liuex/articles/244455.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liuex/comments/commentRss/244455.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liuex/services/trackbacks/244455.html</trackback:ping><description><![CDATA[<p>The Java programming language also provides operators that perform bitwise and bit shift operations on integral types. The operators discussed in this section are less commonly used. Therefore, their coverage is brief; the intent is to simply make you aware that these operators exist. </p>
<p>The unary bitwise complement operator "~" inverts a bit pattern; it can be applied to any of the integral types, making every "0" a "1" and every "1" a "0". For example, a byte contains 8 bits; applying this operator to a value whose bit pattern is "00000000" would change its pattern to "11111111". </p>
<p>The signed left shift operator "&lt;&lt;" shifts a bit pattern to the left, and the signed right shift operator "&gt;&gt;" shifts a bit pattern to the right. The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand. The unsigned right shift operator "&gt;&gt;&gt;" shifts a zero into the leftmost position, while the leftmost position after "&gt;&gt;" depends on sign extension. </p>
<p>The bitwise &amp; operator performs a bitwise AND operation. </p>
<p>The bitwise ^ operator performs a bitwise exclusive OR operation. </p>
<p>The bitwise | operator performs a bitwise inclusive OR operation.</p>
<img src ="http://www.blogjava.net/liuex/aggbug/244455.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuex/" target="_blank">Daniel Liu</a> 2008-12-04 22:01 <a href="http://www.blogjava.net/liuex/articles/244455.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>The "Double-Checked Locking is Broken" Declaration</title><link>http://www.blogjava.net/liuex/articles/Favorites.html</link><dc:creator>Daniel Liu</dc:creator><author>Daniel Liu</author><pubDate>Wed, 03 Dec 2008 16:00:00 GMT</pubDate><guid>http://www.blogjava.net/liuex/articles/Favorites.html</guid><wfw:comment>http://www.blogjava.net/liuex/comments/244238.html</wfw:comment><comments>http://www.blogjava.net/liuex/articles/Favorites.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liuex/comments/commentRss/244238.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liuex/services/trackbacks/244238.html</trackback:ping><description><![CDATA[<h1 align="center">The "Double-Checked Locking is Broken" Declaration </h1>
<p align="center"><em>Signed by</em>: <a href="http://www.research.ibm.com/people/d/dfb">David Bacon</a> (IBM Research) Joshua Bloch (Javasoft), <a href="http://www.cs.ucsb.edu/~bogda/">Jeff Bogda</a>, Cliff Click (Hotspot JVM project), <a href="http://www.webcom.com/~haahr/">Paul Haahr</a>, <a href="http://www.cs.oswego.edu/~dl">Doug Lea</a>, <a href="mailto:tom@go2net.com">Tom May</a>, <a href="http://www.csg.lcs.mit.edu/~earwig/">Jan-Willem Maessen</a>, <a href="http://www.cs.umd.edu/~jmanson">Jeremy Manson</a>, <a href="http://www.jGuru.com/johnm">John D. Mitchell (jGuru)</a> Kelvin Nilsen, <a href="http://www.cs.umd.edu/~pugh">Bill Pugh</a>, <a href="http://www.cs.washington.edu/homes/egs/">Emin Gun Sirer</a>
<p>Double-Checked Locking is widely cited and used as an efficient method for implementing lazy initialization in a multithreaded environment.
<p>Unfortunately, it will not work reliably in a platform independent way when implemented in Java, without additional synchronization. When implemented in other languages, such as C++, it depends on the memory model of the processor, the reorderings performed by the compiler and the interaction between the compiler and the synchronization library. Since none of these are specified in a language such as C++, little can be said about the situations in which it will work. Explicit memory barriers can be used to make it work in C++, but these barriers are not available in Java.
<p>To first explain the desired behavior, consider the following code:
<p>
<table border="2">
    <tbody>
        <tr>
            <td>
            <pre>// Single threaded version
            class Foo {
            private Helper helper = null;
            public Helper getHelper() {
            if (helper == null)
            helper = new Helper();
            return helper;
            }
            // other functions and members...
            }
            </pre>
        </tr>
    </tbody>
</table>
<p>If this code was used in a multithreaded context, many things could go wrong. Most obviously, two or more <tt>Helper</tt> objects could be allocated. (We'll bring up other problems later). The fix to this is simply to synchronize the <tt>getHelper()</tt> method:
<p>
<table border="2">
    <tbody>
        <tr>
            <td>
            <pre>// Correct multithreaded version
            class Foo {
            private Helper helper = null;
            public synchronized Helper getHelper() {
            if (helper == null)
            helper = new Helper();
            return helper;
            }
            // other functions and members...
            }
            </pre>
        </tr>
    </tbody>
</table>
<p>The code above performs synchronization every time <tt>getHelper()</tt> is called. The double-checked locking idiom tries to avoid synchronization after the helper is allocated:
<p>
<table border="2">
    <tbody>
        <tr>
            <td>
            <pre>// Broken multithreaded version
            // "Double-Checked Locking" idiom
            class Foo {
            private Helper helper = null;
            public Helper getHelper() {
            if (helper == null)
            synchronized(this) {
            if (helper == null)
            helper = new Helper();
            }
            return helper;
            }
            // other functions and members...
            }
            </pre>
        </tr>
    </tbody>
</table>
<p>Unfortunately, that code just does not work in the presence of either optimizing compilers or shared memory multiprocessors.
<h2>It doesn't work</h2>
<p>There are lots of reasons it doesn't work. The first couple of reasons we'll describe are more obvious. After understanding those, you may be tempted to try to devise a way to "fix" the double-checked locking idiom. Your fixes will not work: there are more subtle reasons why your fix won't work. Understand those reasons, come up with a better fix, and it still won't work, because there are even more subtle reasons.
<p>Lots of very smart people have spent lots of time looking at this. There is <em>no way</em> to make it work without requiring each thread that accesses the helper object to perform synchronization.
<h3>The first reason it doesn't work</h3>
<p>The most obvious reason it doesn't work it that the writes that initialize the <tt>Helper</tt> object and the write to the <tt>helper</tt> field can be done or perceived out of order. Thus, a thread which invokes getHelper() could see a non-null reference to a helper object, but see the default values for fields of the helper object, rather than the values set in the constructor.
<p>If the compiler inlines the call to the constructor, then the writes that initialize the object and the write to the <tt>helper</tt> field can be freely reordered if the compiler can prove that the constructor cannot throw an exception or perform synchronization.
<p>Even if the compiler does not reorder those writes, on a multiprocessor the processor or the memory system may reorder those writes, as perceived by a thread running on another processor.
<p>Doug Lea has written a <a href="http://gee.cs.oswego.edu/dl/cpj/jmm.html">more detailed description of compiler-based reorderings</a>.
<h4>A test case showing that it doesn't work</h4>
<p>Paul Jakubik found an example of a use of double-checked locking that did not work correctly. <a href="DoubleCheckTest.java">A slightly cleaned up version of that code is available here</a>.
<p>When run on a system using the Symantec JIT, it doesn't work. In particular, the Symantec JIT compiles
<center>
<pre>singletons[i].reference = new Singleton();</pre>
</center>
<p>to the following (note that the Symantec JIT using a handle-based object allocation system).
<pre>0206106A   mov         eax,0F97E78h
0206106F   call        01F6B210                  ; allocate space for
; Singleton, return result in eax
02061074   mov         dword ptr [ebp],eax       ; EBP is &amp;singletons[i].reference
; store the unconstructed object here.
02061077   mov         ecx,dword ptr [eax]       ; dereference the handle to
; get the raw pointer
02061079   mov         dword ptr [ecx],100h      ; Next 4 lines are
0206107F   mov         dword ptr [ecx+4],200h    ; Singleton's inlined constructor
02061086   mov         dword ptr [ecx+8],400h
0206108D   mov         dword ptr [ecx+0Ch],0F84030h
</pre>
<p>As you can see, the assignment to <tt>singletons[i].reference</tt> is performed before the constructor for Singleton is called. This is completely legal under the existing Java memory model, and also legal in C and C++ (since neither of them have a memory model).
<h4>A fix that doesn't work</h4>
<p>Given the explanation above, a number of people have suggested the following code:
<p>
<table border="2">
    <tbody>
        <tr>
            <td>
            <pre>// (Still) Broken multithreaded version
            // "Double-Checked Locking" idiom
            class Foo {
            private Helper helper = null;
            public Helper getHelper() {
            if (helper == null) {
            Helper h;
            synchronized(this) {
            h = helper;
            if (h == null)
            synchronized (this) {
            h = new Helper();
            } // release inner synchronization lock
            helper = h;
            }
            }
            return helper;
            }
            // other functions and members...
            }
            </pre>
        </tr>
    </tbody>
</table>
<p>This code puts construction of the Helper object inside an inner synchronized block. The intuitive idea here is that there should be a memory barrier at the point where synchronization is released, and that should prevent the reordering of the initialization of the <tt>Helper</tt> object and the assignment to the field helper.
<p>Unfortunately, that intuition is absolutely wrong. The rules for synchronization don't work that way. The rule for a monitorexit (i.e., releasing synchronization) is that actions before the monitorexit must be performed before the monitor is released. However, there is no rule which says that actions after the monitorexit may not be done before the monitor is released. It is perfectly reasonable and legal for the compiler to move the assignment <tt>helper = h;</tt> inside the synchronized block, in which case we are back where we were previously. Many processors offer instructions that perform this kind of one-way memory barrier. Changing the semantics to require releasing a lock to be a full memory barrier would have performance penalties. <!--
<p>Another problem is that the compiler can see that the inner synchronization
block is redundant and eliminate it.
-->
<h4><a name="readersNeedSync">More fixes that don't work</a></h4>
<p>There is something you can do to force the writer to perform a full bidirectional memory barrier. This is gross, inefficient, and is almost guaranteed not to work once the Java Memory Model is revised. Do not use this. In the interests of science, <a href="BidirectionalMemoryBarrier.html">I've put a description of this technique on a separate page.</a> Do not use it.
<p><em>However</em>, even with a full memory barrier being performed by the thread that initializes the helper object, it still doesn't work.
<p>The problem is that on some systems, the thread which sees a non-null value for the <tt>helper</tt> field also needs to perform memory barriers.
<p>Why? Because processors have their own locally cached copies of memory. On some processors, unless the processor performs a cache coherence instruction (e.g., a memory barrier), reads can be performed out of stale locally cached copies, even if other processors used memory barriers to force their writes into global memory.
<p>I've created <a href="AlphaReordering.html">a separate web page</a> with a discussion of how this can actually happen on an Alpha processor.
<h2>Is it worth the trouble?</h2>
<p>For most applications, the cost of simply making the <tt>getHelper()</tt> method synchronized is not high. You should only consider this kind of detailed optimizations if you know that it is causing a substantial overhead for an application.
<p>Very often, more high level cleverness, such as using the builtin mergesort rather than handling exchange sort (see the SPECJVM DB benchmark) will have much more impact.
<h2>Making it work for static singletons</h2>
<p>If the singleton you are creating is static (i.e., there will only be one <tt>Helper</tt> created), as opposed to a property of another object (e.g., there will be one <tt>Helper</tt> for each <tt>Foo</tt> object, there is a simple and elegant solution.
<p>Just define the singleton as a static field in a separate class. The semantics of Java guarantee that the field will not be initialized until the field is referenced, and that any thread which accesses the field will see all of the writes resulting from initializing that field.
<p>
<table border="2">
    <tbody>
        <tr>
            <td>
            <pre>class HelperSingleton {
            static Helper singleton = new Helper();
            }
            </pre>
        </tr>
    </tbody>
</table>
<h2>It will work for 32-bit primitive values</h2>
<p>Although the double-checked locking idiom cannot be used for references to objects, it can work for 32-bit primitive values (e.g., int's or float's). Note that it does not work for long's or double's, since unsynchronized reads/writes of 64-bit primitives are not guaranteed to be atomic.
<p>
<table border="2">
    <tbody>
        <tr>
            <td>
            <pre>// Correct Double-Checked Locking for 32-bit primitives
            class Foo {
            private int cachedHashCode = 0;
            public int hashCode() {
            int h = cachedHashCode;
            if (h == 0)
            synchronized(this) {
            if (cachedHashCode != 0) return cachedHashCode;
            h = computeHashCode();
            cachedHashCode = h;
            }
            return h;
            }
            // other functions and members...
            }
            </pre>
        </tr>
    </tbody>
</table>
<p>In fact, assuming that the computeHashCode function always returned the same result and had no side effects (i.e., idempotent), you could even get rid of all of the synchronization.
<p>
<table border="2">
    <tbody>
        <tr>
            <td>
            <pre>// Lazy initialization 32-bit primitives
            // Thread-safe if computeHashCode is idempotent
            class Foo {
            private int cachedHashCode = 0;
            public int hashCode() {
            int h = cachedHashCode;
            if (h == 0) {
            h = computeHashCode();
            cachedHashCode = h;
            }
            return h;
            }
            // other functions and members...
            }
            </pre>
        </tr>
    </tbody>
</table>
<h2><a name="explicitMemoryBarriers">Making it work with explicit memory barriers</a></h2>
<p>It is possible to make the double checked locking pattern work if you have explicit memory barrier instructions. For example, if you are programming in C++, you can use the code from Doug Schmidt et al.'s book:
<p>
<table border="2">
    <tbody>
        <tr>
            <td>
            <pre>// C++ implementation with explicit memory barriers
            // Should work on any platform, including DEC Alphas
            // From "Patterns for Concurrent and Distributed Objects",
            // by Doug Schmidt
            template &lt;class TYPE, class LOCK&gt; TYPE *
            Singleton&lt;TYPE, LOCK&gt;::instance (void) {
            // First check
            TYPE* tmp = instance_;
            // Insert the CPU-specific memory barrier instruction
            // to synchronize the cache lines on multi-processor.
            asm ("memoryBarrier");
            if (tmp == 0) {
            // Ensure serialization (guard
            // constructor acquires lock_).
            Guard&lt;LOCK&gt; guard (lock_);
            // Double check.
            tmp = instance_;
            if (tmp == 0) {
            tmp = new TYPE;
            // Insert the CPU-specific memory barrier instruction
            // to synchronize the cache lines on multi-processor.
            asm ("memoryBarrier");
            instance_ = tmp;
            }
            return tmp;
            }
            </pre>
        </tr>
    </tbody>
</table>
<h2><a name="ThreadLocal">Fixing Double-Checked Locking using Thread Local Storage</a></h2>
<p>Alexander Terekhov (TEREKHOV@de.ibm.com) came up clever suggestion for implementing double checked locking using thread local storage. Each thread keeps a thread local flag to determine whether that thread has done the required synchronization.
<table>
    <tbody>
        <tr>
            <td>
            <pre>  class Foo {
            /** If perThreadInstance.get() returns a non-null value, this thread
            has done synchronization needed to see initialization
            of helper */
            private final ThreadLocal perThreadInstance = new ThreadLocal();
            private Helper helper = null;
            public Helper getHelper() {
            if (perThreadInstance.get() == null) createHelper();
            return helper;
            }
            private final void createHelper() {
            synchronized(this) {
            if (helper == null)
            helper = new Helper();
            }
            // Any non-null value would do as the argument here
            perThreadInstance.set(perThreadInstance);
            }
            }
            </pre>
        </tr>
    </tbody>
</table>
<p>The performance of this technique depends quite a bit on which JDK implementation you have. In Sun's 1.2 implementation, ThreadLocal's were very slow. They are significantly faster in 1.3, and are expected to be faster still in 1.4. <a href="DCL-performance.html">Doug Lea analyzed the performance of some techniques for implementing lazy initialization</a>.
<h2>Under the new Java Memory Model</h2>
<p>As of JDK5, there is <a href="/~pugh/java/memoryModel">a new Java Memory Model and Thread specification</a>.
<h3>Fixing Double-Checked Locking using Volatile</h3>
<p>JDK5 and later extends the semantics for volatile so that the system will not allow a write of a volatile to be reordered with respect to any previous read or write, and a read of a volatile cannot be reordered with respect to any following read or write. See <a href="http://jeremymanson.blogspot.com/2008/05/double-checked-locking.html">this entry in Jeremy Manson's blog</a> for more details.
<p>With this change, the Double-Checked Locking idiom can be made to work by declaring the <tt>helper</tt> field to be volatile. This <em>does not work</em> under JDK4 and earlier.
<p>
<table border="2">
    <tbody>
        <tr>
            <td>
            <pre>// Works with acquire/release semantics for volatile
            // Broken under current semantics for volatile
            class Foo {
            private volatile Helper helper = null;
            public Helper getHelper() {
            if (helper == null) {
            synchronized(this) {
            if (helper == null)
            helper = new Helper();
            }
            }
            return helper;
            }
            }
            </pre>
        </tr>
    </tbody>
</table>
<h3>Double-Checked Locking Immutable Objects</h3>
<p>If Helper is an immutable object, such that all of the fields of Helper are final, then double-checked locking will work without having to use volatile fields. The idea is that a reference to an immutable object (such as a String or an Integer) should behave in much the same way as an int or float; reading and writing references to immutable objects are atomic.
<h1>Descriptions of double-check idiom</h1>
<ul>
    <li><a href="http://www.cs.wustl.edu/~schmidt/editorial-3.html">Reality Check</a>, Douglas C. Schmidt, C++ Report, SIGS, Vol. 8, No. 3, March 1996.
    <li><a href="http://www.cs.wustl.edu/~schmidt/DC-Locking.ps.gz">Double-Checked Locking: An Optimization Pattern for Efficiently Initializing and Accessing Thread-safe Objects</a>, Douglas Schmidt and Tim Harrison. <em>3rd annual Pattern Languages of Program Design conference</em>, 1996
    <li><a href="http://www.javaworld.com/javaworld/javatips/jw-javatip67.html">Lazy instantiation</a>, Philip Bishop and Nigel Warren, JavaWorld Magazine
    <li><a href="http://www.javaworld.com/javaworld/jw-04-1999/jw-04-toolbox-3.html">Programming Java threads in the real world, Part 7</a>, Allen Holub, Javaworld Magazine, April 1999.
    <li><a href="http://www.phptr.com/ptrbooks/ptr_0130142603.html"><em>Java 2 Performance and Idiom Guide</em></a>, Craig Larman and Rhett Guthrie, p100.
    <li><a href="http://www.google.com/search?q=Java+Design+Styles+Nigel+Bishop"><em>Java in Practice: Design Styles and Idioms for Effective Java</em></a>, Nigel Warren and Philip Bishop, p142.
    <li>Rule 99, <a href="http://www.google.com/search?q=elements+java+style+Ambler"><em>The Elements of Java Style</em></a>, Allan Vermeulen, Scott Ambler, Greg Bumgardner, Eldon Metz, Trvor Misfeldt, Jim Shur, Patrick Thompson, SIGS Reference library
    <li><a href="http://gamelan.earthweb.com/journal/techfocus/022300_singleton.html">Global Variables in Java with the Singleton Pattern</a>, Wiebe de Jong, Gamelan </li>
</ul>
 <img src ="http://www.blogjava.net/liuex/aggbug/244238.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuex/" target="_blank">Daniel Liu</a> 2008-12-04 00:00 <a href="http://www.blogjava.net/liuex/articles/Favorites.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Singleton Pattern implements in Java</title><link>http://www.blogjava.net/liuex/articles/244237.html</link><dc:creator>Daniel Liu</dc:creator><author>Daniel Liu</author><pubDate>Wed, 03 Dec 2008 15:46:00 GMT</pubDate><guid>http://www.blogjava.net/liuex/articles/244237.html</guid><wfw:comment>http://www.blogjava.net/liuex/comments/244237.html</wfw:comment><comments>http://www.blogjava.net/liuex/articles/244237.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liuex/comments/commentRss/244237.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liuex/services/trackbacks/244237.html</trackback:ping><description><![CDATA[<p>Implementing Singleton Pattern<br />
</p>
<p><br />
1. General Steps<br />
To implement this design pattern we need to consider the following 4 steps: <br />
Step 1: Provide a default Private constructor<br />
public class SingletonObjectDemo {</p>
<p>&nbsp;// Note that the constructor is private<br />
&nbsp;private SingletonObjectDemo() {<br />
&nbsp;&nbsp;// Optional Code<br />
&nbsp;}<br />
}</p>
<p><br />
Step 2: Create a Method for getting the reference to the Singleton Objectpublic class SingletonObjectDemo {</p>
<p>&nbsp;private static SingletonObject singletonObject;<br />
&nbsp;// Note that the constructor is private<br />
&nbsp;private SingletonObjectDemo() {<br />
&nbsp;&nbsp;// Optional Code<br />
&nbsp;}<br />
&nbsp;public static SingletonObjectDemo getSingletonObject() {<br />
&nbsp;&nbsp;if (singletonObject == null) {<br />
&nbsp;&nbsp;&nbsp;singletonObject = new SingletonObjectDemo();<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;return singletonObject;<br />
&nbsp;}<br />
}</p>
<p>&nbsp;</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp; We write a public static getter or access method to get the instance of the Singleton Object at runtime. First time the object is created inside this method as it is null. Subsequent calls to this method returns the same object created as the object is globally declared (private) and the hence the same referenced object is returned.</p>
<p>Step 3: Make the Access method Synchronized to prevent Thread Problems.</p>
<p>public static synchronized SingletonObjectDemo getSingletonObject()</p>
<p>It could happen that the access method may be called twice from 2 different classes at the same time and hence more than one object being created. This could violate the design patter principle. In order to prevent the simultaneous invocation of the getter method by 2 threads or classes simultaneously we add the synchronized keyword to the method declaration</p>
<p>Step 4: Override the Object clone method to prevent cloning</p>
<p>We can still be able to create a copy of the Object by cloning it using the Object&#8217;s clone method. This can be done as shown below</p>
<p>SingletonObjectDemo clonedObject = (SingletonObjectDemo) obj.clone();</p>
<p>This again violates the Singleton Design Pattern's objective. So to deal with this we need to override the Object&#8217;s clone method which throws a CloneNotSupportedException exception.</p>
<p>public Object clone() throws CloneNotSupportedException {<br />
throw new CloneNotSupportedException(); <br />
}</p>
<p>The below program shows the final Implementation of Singleton Design Pattern in java, by using all the 4 steps mentioned above.class SingletonClass {</p>
<p>&nbsp;private static SingletonClass singletonObject;<br />
&nbsp;/** A private Constructor prevents any other class from instantiating. */<br />
&nbsp;private SingletonClass() {<br />
&nbsp;&nbsp;//&nbsp; Optional Code<br />
&nbsp;}<br />
&nbsp;public static synchronized SingletonClass getSingletonObject() {<br />
&nbsp;&nbsp;if (singletonObject == null) {<br />
&nbsp;&nbsp;&nbsp;singletonObject = new SingletonClass();<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;return singletonObject;<br />
&nbsp;}<br />
&nbsp;public Object clone() throws CloneNotSupportedException {<br />
&nbsp;&nbsp;throw new CloneNotSupportedException();<br />
&nbsp;}<br />
}</p>
<p>public class SingletonObjectDemo {</p>
<p>&nbsp;public static void main(String args[]) {<br />
&nbsp;&nbsp;//&nbsp;&nbsp;SingletonClass obj = new SingletonClass();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Compilation error not allowed<br />
&nbsp;&nbsp;SingletonClass obj = SingletonClass.getSingletonObject();<br />
&nbsp;&nbsp;// Your Business Logic<br />
&nbsp;&nbsp;System.out.println("Singleton object obtained");<br />
&nbsp;}<br />
}<br />
<br />
2. Implemetion principles</p>
<p>(1).The solution of Bill Pugh</p>
<p>This is the recommended method. It is known as the initialization on demand holder idiom and is as lazy as possible. Moreover, it works in all known versions of Java. This solution is the most portable across different Java compilers and virtual machines.</p>
<p>The inner class is referenced no earlier (and therefore loaded no earlier by the class loader) than the moment that getInstance() is called. Thus, this solution is thread-safe without requiring special language constructs (i.e. volatile and/or synchronized).<br />
&nbsp;public class Singleton {<br />
&nbsp;&nbsp; // Protected constructor is sufficient to suppress unauthorized calls to the constructor<br />
&nbsp;&nbsp; protected Singleton() {}<br />
&nbsp;<br />
&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp; * SingletonHolder is loaded on the first execution of Singleton.getInstance() <br />
&nbsp;&nbsp;&nbsp; * or the first access to SingletonHolder.INSTANCE , not before.<br />
&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp; private static class SingletonHolder { <br />
&nbsp;&nbsp;&nbsp;&nbsp; private final static Singleton INSTANCE = new Singleton();<br />
&nbsp;&nbsp; }<br />
&nbsp;<br />
&nbsp;&nbsp; public static Singleton getInstance() {<br />
&nbsp;&nbsp;&nbsp;&nbsp; return SingletonHolder.INSTANCE;<br />
&nbsp;&nbsp; }<br />
&nbsp;}</p>
<p><br />
(2).Traditional simple way</p>
<p>Just like the one above, this solution is thread-safe without requiring special language constructs, but it lacks the laziness. The INSTANCE is created as soon as the Singleton class loads. That might even be long before getInstance() is called. It might be (for example) when some static method of the class is used. If laziness is not needed or the instance needs to be created early in the application's execution, this (slightly) simpler solution can be used:<br />
&nbsp;public class Singleton {<br />
&nbsp;&nbsp; public final static Singleton INSTANCE = new Singleton();<br />
&nbsp;<br />
&nbsp;&nbsp; // Protected constructor is sufficient to suppress unauthorized calls to the constructor<br />
&nbsp;&nbsp; protected Singleton() {}<br />
&nbsp;}</p>
<p>Sometimes the static final field is made private and a static factory-method is provided to get the instance. This way the underlying implementation may change easily while it has no more performance-issues on modern JVMs.</p>
<p><br />
(3).Java 5 solution</p>
<p>If and only if the compiler used is Java 5 (also known as Java 1.5) or newer, AND all Java virtual machines the application is going to run on fully support the Java 5 memory model, then (and only then) the volatile double checked locking can be used (for a detailed discussion of why it should never be done before Java 5 see The "Double-Checked Locking is Broken" Declaration):<br />
&nbsp;public class Singleton {<br />
&nbsp;&nbsp; private static volatile Singleton INSTANCE;<br />
&nbsp;<br />
&nbsp;&nbsp; // Protected constructor is sufficient to suppress unauthorized calls to the constructor<br />
&nbsp;&nbsp; protected Singleton() {}<br />
&nbsp;<br />
&nbsp;&nbsp; public static Singleton getInstance() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (INSTANCE == null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized(Singleton.class) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (INSTANCE == null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INSTANCE = new Singleton();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return INSTANCE;<br />
&nbsp;&nbsp; }<br />
}</p>
<p>Allen Holub (in "Taming Java Threads", Berkeley, CA: Apress, 2000, pp. 176&#8211;178) notes that on multi-CPU systems (which are widespread as of 2007), the use of volatile may have an impact on performance approaching to that of synchronization, and raises the possibility of other problems. Thus this solution has little to recommend it over Pugh's solution described above.</p>
<p><br />
(4).The Enum-way</p>
<p>In the second edition of his book "Effective Java" Joshua Bloch claims that "a single-element enum type is the best way to implement a singleton" for any Java that supports enums. The use of an enum is very easy to implement and has no drawbacks regarding serializable objects, which have to be circumvented in the other ways.<br />
&nbsp;public enum Singleton {<br />
&nbsp;&nbsp; INSTANCE;<br />
&nbsp;}</p>
<img src ="http://www.blogjava.net/liuex/aggbug/244237.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuex/" target="_blank">Daniel Liu</a> 2008-12-03 23:46 <a href="http://www.blogjava.net/liuex/articles/244237.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML Character Reference</title><link>http://www.blogjava.net/liuex/articles/242906.html</link><dc:creator>Daniel Liu</dc:creator><author>Daniel Liu</author><pubDate>Wed, 26 Nov 2008 15:31:00 GMT</pubDate><guid>http://www.blogjava.net/liuex/articles/242906.html</guid><wfw:comment>http://www.blogjava.net/liuex/comments/242906.html</wfw:comment><comments>http://www.blogjava.net/liuex/articles/242906.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/liuex/comments/commentRss/242906.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/liuex/services/trackbacks/242906.html</trackback:ping><description><![CDATA[<p>A numeric character reference refers to a character by its Universal Character Set/Unicode code point, and uses the format<br />
&#nnnn;</p>
<p>or<br />
&#xhhhh;</p>
<p>where nnnn is the code point in decimal form, and hhhh is the code point in hexadecimal form. The x must be lowercase in XML documents. The nnnn or hhhh may be any number of digits and may include leading zeros. The hhhh may mix uppercase and lowercase, though uppercase is the usual style.<br />
<br />
(see <a title="wiki" href="http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references">wiki</a>)</p>
<img src ="http://www.blogjava.net/liuex/aggbug/242906.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/liuex/" target="_blank">Daniel Liu</a> 2008-11-26 23:31 <a href="http://www.blogjava.net/liuex/articles/242906.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>