Single mode of Java interview

The following article is from WeChat public  account Xiaoha Learn Java , author AllenJiang

The singleton pattern is the simplest design pattern among the 23 kinds of GOF (design patterns) and the most classic design pattern. In the Java interview, it can be said that it is a necessary knowledge point. Next, let's talk about it in detail.

Interviewer: Are you familiar with design patterns? What design patterns have you used in your work?

Applicants: There are singleton mode, factory mode, chain of responsibility mode, agency mode commonly used in work ...

Interviewer: Oh! Now that you mentioned the singleton pattern, what would you say is the singleton pattern? Why use singleton mode? There are several singleton modes? What should I pay attention to when using it?

In general, the interviewer cuts into the knowledge point of the singleton mode through the above dialogue.

What is the singleton pattern?

In simple terms, the single-column mode is to ensure that there is only one instance of an object in memory during the life of the program. That is, there is only one object for a class.

Why use singleton mode?

Use singleton mode is nothing more than to improve the execution performance of the code, we can talk about the following two points:

  • 1. Save memory resources

  • 2. Save time (time to allocate objects)

The first is to save memory resources. For some large objects in the program, these objects occupy a large amount of memory. Frequent creation not only increases memory overhead, but also consumes a lot of memory allocation time. In addition, frequent GC (garbage collection) and GC It will increase the time overhead. In serious cases, Full GC may also occur, causing the main thread of the program to block. These are intolerable. The single-row model was born in this situation.

Are there several singleton patterns?

Normally we say five kinds are enough, but in order to show our broad knowledge, we can say this:

Candidates: There are 7 types of subdivided singleton models, but strictly speaking there are only 5 types. Let me talk about the seven subdivisions:

The first: lazy, unsafe thread

public class Singleton {  

  private static Singleton instance;  

  private Singleton (){}   

  public static Singleton getInstance() {  
  if (instance == null) {  
    instance = new Singleton();}  
  return instance;  
  }  

This writing method is lazy loading. The fatal thing is that in the case of multithreading, there will be multiple instances of Singleton objects instantiated.

The second kind: lazy, thread-safe

public class Singleton {
  private static Singleton instance;
  private Singleton (){}

  public static synchronized Singleton getInstance() {
    if (instance == null) {
      instance = new Singleton();}
    return instance;
  }
}

This way of writing works well in a multi-threaded environment, and also has the advantage of lazy loading, but, unfortunately, the efficiency is very low, and synchronization is not required in 99% of cases.

The third type: hungry Chinese

public class Singleton {  

   private static Singleton instance = new Singleton();  

   private Singleton (){}

   public static Singleton getInstance() {  
    return instance;  
}

This method is based on the java class loading mechanism to avoid the problem of multi-thread synchronization, but because of this, the instance is instantiated when it is loaded, and there are many reasons for instantiation. Sometimes, we are not willing to use it Instantiated. And the singleton mode most of the instantiation is to call getInstance () method, which violates the design of lazy loading.

Note 1: The interviewer may also ask you: When is the instance initialized?

The instance will be initialized when the class is loaded. When it comes to class loading, there is no mandatory constraint in the JVM virtual machine specification at what specific time to load the class, but regarding the initialization of the class, the virtual machine strictly stipulates that there are only There are 4 situations, respectively, when the following 4 bytecodes are specified:

  • 1. new

  • 2. getStatic

  • 3. putStatic

  • 4. invokeStatic

When encountering the above 4 byte designation codes, if the class has not been initialized, you need to trigger its initialization first.

As for when to generate the above 4 instructions, they correspond to the following scenarios:

  • 1. Use the new  keyword to instantiate the object ==> corresponding to the new instruction ;  

  • 2. Read the static field of a class (except for the static field modified by final and put the result in the constant pool at compile time) ==> corresponding to the getStatic instruction ; 

  • 3. Set static field of a class (the final modification, the results have been compiled in a static field of the constant pool except) ==> corresponds putStatic instruction ; 

  • 4. Call a static method of a class ==> corresponding to the invokeStatic instruction ; 

Note 2: The interviewer may also ask your JVM class loading mechanism?

At this time, you can talk about the classloader parent delegation model, which will not be described here.

Fourth type: Hungry man, variant

public class Singleton {  
    private Singleton instance = null;  

    static {  
      instance = new Singleton();
    }  

    private Singleton (){}

    public static Singleton getInstance() {  
    return this.instance;  
    }  

Here, the static block is used to instantiate the object, which is actually similar to the third one.

Fifth: static inner class

public class Singleton {  

    private static class SingletonHolder { 
      private static final Singleton INSTANCE = new Singleton();
    }  

    private Singleton (){}

    public static final Singleton getInstance() {  
      return SingletonHolder.INSTANCE;  
    }  

This method also uses the classloder mechanism to ensure that there is only one thread when initializing the instance. It is different from the third and fourth methods (very slight difference): the third and fourth methods are as long as the Singleton class If it is loaded, then the instance will be instantiated (without the lazy loading effect), and in this way, the Singleton class is loaded, and the instance may not be initialized. Because the SingletonHolder class is not actively used, only when it is shown that the getInstance method is called, the SingletonHolder class is displayed and the instance is instantiated. Imagine that if instantiating an instance consumes resources, I want him to delay loading. On the other hand, I do n’t want to instantiate when the Singleton class is loaded, because I ca n’t ensure that the Singleton class may be actively used elsewhere Is loaded, then it is obviously inappropriate to instantiate an instance at this time. At this time, this method is quite reasonable compared to the third and fourth methods.

Sixth: enumeration

 public enum Singleton {  
   INSTANCE;  
   public void whateverMethod(){}  
 } 

This method is advocated by the author of "Effective Java" Josh Bloch. It not only avoids multi-thread synchronization problems, but also automatically avoids serialization / deserialization attacks and reflection attacks (enumeration classes cannot be generated by reflection).

Seventh: Double Check Lock (DCL)

public class Singleton {  

    private volatile static Singleton singleton;  

    private Singleton (){}   

    public static Singleton getSingleton() {  
    if (singleton == null) {  
      synchronized (Singleton.class) {  
      if (singleton == null) {  
        singleton = new Singleton();}  
     }  
   }  
   return singleton;  
   }  
 } 

This is an upgraded version of the second method, commonly known as double check lock. By adding a layer of judgment outside the synchronized, you can no longer enter the synchronized block once the object is created. This scheme not only reduces the granularity of the lock, ensures thread safety, but also greatly improves performance.

At the same time, you also need to talk about the role of the keyword volidate to prevent JVM instruction rearrangement. For details, you can read my other article "The volatile Keywords You Must Know" . 

to sum up

But generally speaking, the first kind is not a single case, the fourth kind and the third kind is one kind, if counted, the fifth kind can be written separately. Therefore, the general single case is written in five ways.

  • 1. a lazy man

  • 2. Hungry man

  • 3. Double Check Lock (DCL)

  • 4. Enumeration

  • 5. Static inner class

  •  

Guess you like

Origin www.cnblogs.com/yujian0817/p/12745698.html