Several forms of the singleton pattern

Source: Internet
Author: User
Tags constructor static class volatile

As for the singleton pattern, I tried to record several forms of the singleton pattern several times before. In the interview before also asked a singleton mode, only remember when I wrote a kind, the interviewer is not very satisfied. Recently I found several articles about the Singleton model, carefully read the next. This paper summarizes several forms of the next singleton pattern, as well as the advantages and disadvantages of each form.

1. A Hungry man type

public class singleton{
   private Singleton () {}
   private static final Singleton single=new Singleton ();
   public static Singleton getinstance () {
   return single;}
}

A hungry man creates an object when the class is loaded, which is a typical space-time change.

The above-mentioned implementation method is called a hungry man, from the code can be seen, only through the Singleton.getinstance () method to obtain the singleton instance, and this instance is a static object, and at the time of the declaration is initialized, This guarantees the uniqueness of the singleton object and will not change in the future. Class loads slowly, but gets objects fast and thread safe.

2. Lazy Type

public class singleton{
   private Singleton () {}
   private static Singleton single=null;
   public static synchronized Singleton getinstance () {
     if (single==null) {
        single=new Singleton ();
     }
     return single;
   }
}

The lazy pattern is judged every time an instance is acquired, which is a typical time-to-change space. The getinstance () method adds the Synchronized keyword, which is described above as a means of guaranteeing the uniqueness of Singleton objects under multithreading. But even if the instance has been initialized, each call to the getinstance () method will be synchronized, wasting unnecessary resources, which is the biggest problem with lazy mode. Therefore, this model is generally not recommended for use.

Synchronized guarantees that only one thread can be executed within a single time, and another thread must wait for the current thread to execute before it can be executed, making the thread safe. The disadvantage is that each call to the GetInstance method synchronizes, causing unnecessary synchronization overhead.

3. Double check (double check Lock), referred to as DCL mode

public class Singleton {
    private static volatile Singleton single = null;

    Private Singleton () {} public

    static Singleton getinstance () {
        ///first-level checksum, in order to avoid unnecessary synchronization
        if (single = null) {
            Synchronized (singleton.class) {
                ///second-level checksum, if the instance is null, create
                if (single = null) Single
                    = new Singleton ();
            }
        }
        return single;
    }
}

The highlight of this approach is that the Singleton.getinstance () method has a two-level null for single and the first layer is empty to avoid unnecessary synchronization, and the second layer is empty to create the instance in the case of single null.

We will find that the volatile keyword is used here, because the initialization of member variables and the order of object instantiation may be disrupted when multiple threads are concurrent, so there is an error, and volatile can prohibit command reordering. Although the double check solves the resource consumption and the redundant synchronization, the thread security problem to some extent, but in some cases the double check failure problem, namely the DCL failure.

DCL Failure problem: Assume that thread a executes to the Single=new Singleton () statement, which looks like a code, in fact it is not an atomic operation, it does roughly three things:

(1) Allocating memory to the instance of single

(2) Call the Singleton constructor to initialize the member fields.

(3) Point the single object to the allocated memory space (single is not NULL at this time)

However, the initialization of member variables and the order of object instantiation is disrupted by concurrent execution of multiple threads. Therefore, the execution order may be 1-2-3, or 1-3-2, if the latter, and 3 is executed, 2 is not executed before being switched to the B thread, the single because already executed in thread a 3rd, single is non-empty, so thread B directly take a single, The problem of the DCL failure is that it will be wrong to use it again.

4. Static internal class Singleton mode

public class Singleton {

    private Singleton () {} public

    static Singleton getinstance () {
        return Singletonholder.single;
    }

    
  private static class Singletonholder {
      private static final Singleton single = new Singleton ();
  }
/**
 * To prevent objects from regenerating objects in deserialization, override the private method of serializable/private
  Object Readresolve () throws objectstreamexception{
      return singletonholder.single;}
}

This is the recommended single-mode implementation method. When the Singleton class is loaded for the first time, it is not initialized and is initialized only the first time the getinstance () is called. This approach not only guarantees thread safety, but also guarantees the uniqueness of singleton objects, and also prolongs the instantiation of singleton cases. The above code overrides the Readresolve () method because it allows you to write a singleton instance object to disk and then read it back to get an instance. Even if the constructor is private, deserialization can still create a new instance of the class in a special way, equivalent to calling the constructor of the class. Deserialization provides a special constructor that has a private, instantiated method, Readresolve (), which allows the developer to control the deserialization of the object. Override this method to return singletonholder.single instead of creating a new instance by default, thus preserving the singleton.

5. Using containers

public class Singletonmanager {
    private Singletonmanager () {}

    private static map<string, object> Instancemap = new hashmap<> ();

    public static void RegisterInstance (String key, Object instance) {
        if (!instancemap.containskey (key)) {
            Instancemap.put (key, instance);
        }
    }

    public static Object getinstance (String key) {
        return instancemap.get (key);
    }
}
public class Singleton {
    Singleton () {} public

    void DoSomething () {
        log.d ("Wxl", "dosomeing");
    }
}

Use:

Singletonmanager.registerinstance ("Singleton", New Singleton ());
Singleton single = (Singleton) singletonmanager.getinstance ("Singleton");
Single.dosomething ();

6. Enumeration

public enum Singletonenum {
    INSTANCE;

    public void DoSomething () {
        log.d ("Wxl", "Singletonenum dosomeing");
    }
}

Use:

SingletonEnum.INSTANCE.doSomething ();
Enumerating the singleton patterns, we may not use much, but the effective Java book recommends this approach, saying that "single-element enumeration types have become the best way to implement Singleton." However, Android uses an enum after the Dex size increased a lot, the runtime will also incur additional memory, so the official strongly recommend not to use an enum in the Android program, enumeration of the shortcomings of the single case is also obvious.

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.