A deep understanding of the implementation of a singleton pattern in Java

Source: Internet
Author: User

A few different implementations of the singleton pattern have been written in previous study notes. This article is mainly to add and deepen the previous note.
· The benefits of using singleton patterns in the Java language:
(1): For frequently used objects, you can omit the time it takes to create the object, especially the creation of heavyweight objects, which is a considerable overhead for the creation of heavyweight objects.
(2): Due to the decrease in the number of new operations, the further benefit is that the frequency of system memory usage will also be reduced, then this action will reduce the GC pressure, shorten the GC pause time.
The above two points have improved the performance of the system.
The implementation of the Singleton pattern:
Simple and reliable type:

publicclass Singleton {    private **staticnew Singleton();    **privateSingleton(){    }    public **staticgetInstance(){        return instance;    }}

The implementation of this singleton pattern is simple and reliable, and the creation of the instance is created by the JVM at the time the class is loaded. But this will take the only disadvantage of this implementation pattern: we cannot delay loading the instance instance. Imagine the following scenario:
When we create a singleton class that plays multiple roles in the system, because the Singleton class instance is created by the JVM, then any active use of that class will trigger the JVM to load the singleton class. The Singleton object is then created, regardless of whether we really need to use the class's instance object at this point.
Modified Type (i):

public   Class  Singleton {private  **static  * *    Singleton instance = new  Singleton (); **private  * * singleton  () {} public  **stati**c Singleton getinstance  () {return  instance; } //this singleton class also takes on other roles, is responsible for generating a random number  public  **static  * * int  generatenumder  () {return  (int ) math.random () * 100 ; }}

At this point, when we use the Generatenumer () method of this class, we may not want to load an instance of the class. Here we introduce a lazy loading mechanism to implement a singleton pattern:
Perfect type:

publicclass LazySingleton{    privatestaticnull;    privateLazySingleton(){}    publicstaticgetInstance(){        ifnull){            new LazySingleton();        }        return instance;    }}

When introducing the lazy loading mechanism, it is necessary to consider the possible problems of the system in the multithreaded environment, so the keyword synchronized and checking the null operation are essential, but the time consuming of the system loading the instance object becomes longer. To optimize the time-consuming bottleneck, we can make improvements such as:

publicclass StaticSingleton{    privateStaticSingleton(){}    privatestaticclass SingletonHolder{        privatestaticnew StaticSingleton();    }    publicstaticgetInstance(){        return SingletonHolder.instance;    }}

In the above implementation, the singleton pattern employs an internal class to maintain a singleton instance object, when the Staticsingleton is loaded, Its inner class is not initialized (in the Staticsingleton class, except that the GetInstance method actively uses the inner class Singletonholder, there is no other place to actively use the inner class, and all does not cause the inner class to initialize). At the same time, the implementation of the instance is inherently friendly to multithreading because it is created by the JVM at class load time. This implementation combines the advantages of both of the above implementations.

In general, we can implement a singleton pattern in one of the three implementations above, but there are exceptions that can cause multiple instances of the system to be generated, and the common in Java is reflection .

Another implementation of the singleton pattern, which is also recommended in effective Java, can be supported after JDK5.0 and implemented using enumerations:

四、枚举,《Effective Java》作者推荐使用的方法,优点:不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象 */publicenum EnumSingleton {    INSTANCE;}

Additional knowledge: The use of the singleton pattern when serializing and deserializing:
A single-tick, serialized pattern implementation Demo:

 Public  class Singleton implements Java. io. Serializable {    PrivateString Clazzname;Private StaticSingleton instance =NewSingleton ();Private Singleton(){ This. Name ="Demo"; } Public StaticSingletongetinstance(){returnInstance } Public**Static**int Generatenumder(){return(int) Math.random () * -; }     ***//block generation of new instances, always return current object    PrivateObjectReadresolve(){returnInstance }***}

Some knowledge about the Readresolve method: quoting from
Http://download.oracle.com/javase/1.5.0/docs/guide/serialization/spec/input.html
For Serializable and Externalizable classes, the Readresolve method allows a class to replace/resolve the object read from The stream before it is returned to the caller. By implementing the Readresolve method, a-class can directly control the types and instances of its own instances being de Serialized. The method is defined as follows:
Any-access-modifier Object Readresolve ()
Throws Objectstreamexception;
The Readresolve method is called when ObjectInputStream have read an object from the stream and are preparing to return it T o the caller. ObjectInputStream checks whether the class of the object defines the Readresolve method. If The method is defined, the Readresolve method was called to allow the object in the stream to designate the object to be Returned. The object returned should be of a type, that's compatible with all uses. If It is not compatible, a classcastexception would be thrown when the type mismatch is discovered.
For example, a Symbol class could is created for which only a single instance of each Symbol binding existed within a virt UAL machine. The Readresolve method would is implemented to determine if the symbol is already defined and substitute the preexisting Equivalent Symbol object to maintain the identity constraint. The uniqueness of Symbol objects can be maintained across serialization.

Note-the Readresolve method is no invoked on the object until the object was fully constructed, so any references to thi S object in its object graph is not being updated to the new object nominated by Readresolve. However, during the serialization of an object with the Writereplace method, all references to the original object in the Replacement object, object graph is replaced with references to the replacement object. Therefore in cases where an object being serialized nominates a replacement object whose object graph have a reference to T He original object, deserialization'll result in an incorrect graph of objects. Furthermore, if the reference types of the object being read (nominated by Writereplace) and the original object is not C Ompatible, the construction of the object graph would raise a classcastexception.
The serialized object is passed to the caller, and when the caller reads the serialized object from the ObjectInputStream stream, the serialized object is returned to the caller to see if the method has been implemented and returns the return value of the object if implemented. If the return value does not match the class type conversion expected by the caller, a classcastexception error is reported.
However, if the serialized object must already be fully constructed when the caller gets the serialized object through the stream, the serialized object will not find this method.

The Readresolve method will be called before ObjectInputStream has read an object and is ready to return. ObjectInputStream checks to see if the object's class defines the Readresolve method. If defined, the returned object is specified by the Readresolve method. The type of the returned object must be compatible, otherwise the classcastexception will be thrown.

A deep understanding of the implementation of a singleton pattern in Java

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.