Java Design Pattern Hundred cases-Singleton mode

Source: Internet
Author: User
Tags volatile

The source of this article see: Https://github.com/get-set/get-designpatterns/tree/master/singleton

The singleton pattern (Singleton pattern) is one of the simplest design patterns in Java, but it is also a well-deserved design pattern, which is a built-in pattern.

The purpose of the singleton pattern is that for some classes, you need to ensure that there is only one instance of it. For example, a counter in the Web, without each refresh in the database record once, you can use a singleton object first cached. But this counter cannot have multiple instances, otherwise it is not allowed.

Specifically, the design pattern has the following characteristics or requirements:

    1. A singleton class can have only one instance.

    2. The Singleton class must create its own unique instance.

    3. The Singleton class must provide this instance to all other objects.

Example a hungry man type

Let's consider the above three requirements.

static A member variable or method of a can be thought of as belonging to the class itself and can be shared by all instances of the class, and can be considered "unique". So with keyword modifies the object of this class to do so.

The Singleton class must then create its own unique instance. That's fine, a singleton class defines itself as a member variable of its own type, and then sets static it to the right. The construction method is then set private so that it cannot be used by other classes or objects new .

Finally, the Singleton class must provide this instance to all other objects. That is to provide a GET method that can get the member variable to this type for itself.

After analysis, the first version of the code:

Singleobject.java

public class Singleobject {private final static singleobject INSTANCE = new Singleobject ();    Private Singleobject () {} public static Singleobject getinstance () {return instance; }}

Let's do a client test:

Client.java

public class Client {public static void main (string[] args) {System.out.println (singleobject.getinstance ());    System.out.println (Singleobject.getinstance ()); }}

return Result:

[Email protected] [Email protected]

As you can see from the hash of the object, two calls getInstance() return the same object.

This is a more commonly used way, called "a Hungry Man-style", why call this self-realization yo ~ We know that when the class loads, static member variables are initialized, so once the class is loaded, then the INSTANCE object being pointed to is created. In fact, this is a regular light, so you can use uppercase, and then final Modify.

Lazy type

In some cases, if the singleton class itself consumes resources or is slow to load, and wants to be able to create instances when used, then lazy loading can be used as follows:

lazysingleobject.java

//  This example is thread insecure public class lazysingleobject {    private static  lazysingleobject instance;    private lazysingleobject ()  {}     public static lazysingleobject getinstance ()  {         if  (instance == null)  {             instance = new lazysingleobject ();         }        return instance;     }} 

So, only in calling getInstance () When the instance is created.

but this approach is thread insecure, assuming that there are two threads calling the getinstance () , instance = = null . So you can put method uses synchronized is decorated to ensure thread safety.

However, in the actual use process, once the instance is created, the getInstance() method simply returns the instance, does not need to synchronize, and the lock will affect the efficiency, so we consider not to lock the whole method, but only the process of the new instance is locked, as follows:

Lazysingleobject.java

  Double check lock/double check lock (DCL, ie  double-checked locking) public class lazysingleobject {     //  use volatile to modify a singleton variable     private static volatile  Lazysingleobject instance;    private lazysingleobject ()  {}     public static lazysingleobject getinstance ()  {         //  first judgment, this time is unlocked         if  (instance  == null)  {            synchronized  (Lazysingleobject.class)  {                 //  second judgment, this is thread-safe                  if  (instance == null)  {           &nbsP;         instance = new lazysingleobject ();                 }             }        }         return instance;    }}

is visible only if the instance is not created ( instance = = null ) When the instance object is created synchronously. In Synchronized the code base, check again if the instance is created because the first check is not thread safe. Therefore, this method is called "Double check lock/double check lock". This way, once the instance is created, it is no longer in sync with the code block, making it more efficient.

instance to use is decorated. The reason is that the compiler needs to reorder the read and write operations of the memory for optimization purposes, so the write operation to the Lazysingleobject object initialization and the write to the instance field can be unordered. The result is that if a thread calls getinstance () it is possible to see the instance field pointing to a Lazysingleobject object, but seeing the field values in that object is the default value. Instead of those values set in the Lazysingleobject constructor method. While using After the volatile field is decorated, both the compiler and the runtime notice that this is a shared variable, so the operation on that variable is not reordered with other memory operations, which is really guaranteed to be thread-safe.

The above two methods can be selected according to the scene.

Registered/Static inner class

If you feel that the "double check lock/Double check Lock" method is complex and difficult to learn, you can use static internal classes to implement thread-safe lazy loading.

Lazyhandlersingleobject.java

public class lazyhandlersingleobject {    private static class  singleobjecthandler {        private final static  lazyhandlersingleobject instance = new lazyhandlersingleobject ();     }    private static LazyHandlerSingleObject instance;     public static lazyhandlersingleobject getinstance ()  {         return singleobjecthandler.instance;    }} 

We know that classes are loaded by Classloder when they are used, and that the static inner classes SingleObjectHandler take advantage of this feature to lazily load instances of their external objects LazyHandlerSingleObject .

Class nesting has always been a difficult concept to understand, and static inner classes are the simplest kind of nested classes, and it's best to think of him as a normal class, but just happen to be declared inside another class. The only thing that differs from the normal class is that static inner classes and their external classes can access all members, including private members, to each other.

When the method is first invoked, it is only used for the first time, getInstance() SingleObjectHandler thus loading it, and naturally creating an LazyHandlerSingleObject instance, SingleObjectHandler by guaranteeing that the static instance is unique.

Enumeration

This implementation has not been widely used, but this is the best way to implement a singleton pattern. It is more concise, automatically supports serialization mechanisms, and absolutely prevents multiple instantiations.

This approach is advocated by effective Java author Josh Bloch, which not only avoids multithreading synchronization problems, but also automatically supports serialization mechanisms, prevents deserialization from recreating new objects, and absolutely prevents multiple instantiations. It is recommended to use this method when you need to use a singleton.

Enumsingleton.java

public enum Enumsingleton {INSTANCE; public void DoSomething () {...}}

It's so simple! EnumSingleton.INSTANCEyou can use it directly, for example EnumSingleton.INSTANCE.doSomething() . Enum types are similar to classes, and can have member variables and member methods.

Summarize

First, try to implement the singleton using enumerations, and the enumeration mechanism itself has a good support for the single case.

If you feel that enumeration is not familiar, then:

Generally, a relatively light-weight single case can be directly used a hungry man;

The weight of a single object, preferably built by lazy loading, according to the requirements of thread safety to choose the two lazy ways; of course, Static inner class is also a good lazy loading mode.


Java Design Pattern Hundred cases-Singleton mode

Related Article

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.