Why I only recommend two Java singleton modes

Time:2020-2-26

Double check mode

public class Singleton { 
 Private volatile static Singleton; // 1: volatile decoration
 private Singleton (){} 
 public static Singleton getSingleton() { 
 If (singleton = = null) {// 2: reduce non synchronization and optimize performance
  Synchronized (singleton. Class) {// 3: synchronization, thread safety
  if (singleton == null) { 
   Singleton = new singleton(); // 4: create singleton object
  } 
  } 
 } 
 return singleton; 
 } 
}

Reasons for recommendation:

  1. Delay initialization. Consistent with lazy mode, the signleton instance is initialized only when the static method getsingleton is called for the first time.
  2. Performance optimization. Synchronization results in performance degradation. Before synchronization, unnecessary synchronization overhead is reduced by reading whether singleton is initialized or not.
  3. Thread safety. Create the singleton object synchronously, and notice that the static variable singleton is decorated with volatile.

Why use volatile decoration?

Although synchronized has been used for synchronization, when you create the object in step 4, you will have the following pseudo code:

Memory = allocate(); // 1: allocate memory space
Ctorinstance(); // 2: initialize object
Singleton = memory; // 3: set singleton to point to the memory space just sorted

When thread a executes the above pseudo code, 2 and 3 may be reordered, because reordering does not affect the running results, but also improves the performance, so the JVM is allowed. If the pseudo code is reordered at this time, the step becomes 1 – > 3 – > 2. When thread a executes to step 3, thread B calls the getsingleton method. If it is not null when it is judged that singleton = = null, then singleton is returned. But at this time, singleton has not been initialized, and thread B will access an object that has not been initialized. When the reference of declared object is volatile, the reordering of pseudo code 2 and 3 will be forbidden in multithreading!

Static inner class pattern


public class Singleton { 
 private Singleton(){
 }
  public static Singleton getSingleton(){ 
  return Inner.instance; 
 } 
 private static class Inner { 
  private static final Singleton instance = new Singleton(); 
 } 
} 

Reasons for recommendation:

  1. The implementation code is simple. Compared with the double check single example, the static internal class single example implementation code is really too concise and clear.
  2. Delay initialization. Call getsingleton to initialize the singleton object.
  3. Thread safety. During the initialization phase of the execution class, the JVM will obtain a lock that can synchronize the initialization of the same class by multiple threads.

How to realize thread safety?

Thread a and thread B are trying to obtain the initialization lock of singleton object at the same time. Assuming thread a obtains the lock, thread B is waiting for the initialization lock. Thread a performs class initialization. Even if the pseudo code in double check mode is reordered, the initialization result of thread a will not be affected. After initialization, release the lock. Thread B obtains the initialization lock, finds that the singleton object has been initialized, releases the lock, does not initialize, and obtains the singleton object.

In singletons involving reflection and serialization, the enumeration type pattern below is recommended.

Other types of singleton mode

Lazy mode (multi thread unsafe)


public class Singleton { 
  private static Singleton instance = new Singleton(); 
  private Singleton (){} 
  public static Singleton getInstance() { 
  return instance; 
  } 
}

Starved Han single instance mode (multi thread security)


public class Singleton { 
  private static Singleton instance = new Singleton(); 
  private Singleton (){} 
  public static Singleton getInstance() { 
  return instance; 
  } 
}

The thread safety of starved mode also solves the synchronization problem by class loading, but it does not achieve the goal of lazy loading. (thank you very much for z-chu’s correction at the beginning.)

Enumerate singleton mode (multithread safe)


public enum Singleton {
  INSTANCE;
  
  public void doSomething(){
    //todo doSomething
  }
}

This method is recommended in Joshua Bloch’s effective Java. Although thread safety has not been widely used in actual development. Because it is too simple to be readable, it has not been widely used in practice. The thread safety of enumeration singleton mode also uses class initialization lock mentioned in static inner class. Enumeration singleton pattern can guarantee the uniqueness of instances in serialization and reflection.

For master to master, you must choose the enumeration singleton mode.

summary

The above is the whole content of this article. I hope that the content of this article has some reference learning value for your study or work. Thank you for your support for developepaer.

Recommended Today

Query SAP multiple database table sizes

Query SAP multiple database table sizes https://www.cnblogs.com/ken-yu/p/12973009.html Item code db02 Here are two approaches, In the first graphical interface, the results of the query data table are displayed in MB, and only one table can be queried at a time. SPACE—Segments—Detailed Analysis—Detailed Analysis  In the pop-up window segment / object, enter the name of the […]