Singleton pattern - static inner classes implement the principles and analysis

  In my experience, for example (if not please correct me), in the production process, often encounter the following two conditions:
  1. The package does not include a class class member variables with specific business meaning, is a business action package, such as the layers in MVC (HTTPRequest object is passed in a manner Threadlocal incoming).

  2. a class has global significance, once instantiated as an object, the object can be used globally. As a class encapsulates the global location information and access information in a location method (without considering the explosion of the earth, plate movement), the information will not change and can be used globally.

  3. Many times the entire system only need to have a global object, this will help us coordinate the overall behavior of the system. The class is used to encapsulate the global configuration information.

  Under all three conditions are created if each time a new object, and the higher the frequency or volume when using larger class object, the object creation and GC frequent cause great waste of resources, while not conducive to the overall behavior of the system coordination. At this time, it needs to consider the use of a singleton object is to achieve the purpose of reuse.

  Before implementing Singleton pattern to see our first look at the four major principles for the use singleton Note:

  1. Private construction. (Block class is instantiated by conventional means)

  2. static method returns an instance or enumeration. (Ensure the uniqueness of instances)

  3. Make sure that only one instance, especially in multithreaded environments. (Thread-safe when you create instances)

  4. Make sure that the object can not be reconstructed during deserialization. (Prevented sequence deserialization scene single embodiment inexplicable damaged, resulting not take into account the consequences)

  There are many ways to achieve Singleton pattern, we only discuss the most widely accepted way of the DCL static inner classes manner (Benpian static inner classes to discuss the way).

  Static inner classes way

  To understand static inner class way, we must first understand the class loading mechanism.

  Class virtual machine loads the file into memory, then verify, parse and initialization, and ultimately the formation of java type, this is the class loading mechanism of the virtual machine. Loading, verification, preparation, parsing initialization sequence five phases are determined, the class loading process must be started in accordance with this order. These phases are usually mutually crossing and the mixing. Resolution phase in some cases, can begin after the initialization stage --- Binding (dynamic binding, the principles of polymorphism) To support when running java language.

  In the Java Virtual Machine Specification, there is no obligation, when to begin loading, however, has strict requirements of the several conditions must be initialized (loading, validation, you need to prepare before the start of initialization):

  1. meet  new, getstatic, putstatic, or invokestatic  this four-byte code instructions, if no class not been initialized, initialization is triggered

  2. Use the method java.lang.reflect package , reflecting the call time, if not initialized, the first trigger initialization

  3. initialize a class time, if we find the parent class is not initialized, the first trigger parent class initialization

  We say that this issue is only relevant to the theme of the initialization phase:

  Class initialization phase is the final phase of class loading process. At this stage, java virtual machine really began to execute java program code in the class definition. At compile time, the compiler will automatically collect all the static variables (class variables) class and a static block of statements (static {} block) statements merger sequentially compiler collected based on statements in the java code order decision. After collected, compiled into java class  static {} method , java virtual machine will ensure static {} class correct method performed in a multi-threaded, or single-threaded environment, and is performed only once . In the process of implementation, we will complete the initialization of class variables. If our java class, not explicitly declared static {} block, if there is a static class variables, the compiler generates a default give us static {} method.

  For static variables, virtual opportunity to ensure that before the static {} subclass of execution, static {} parent class has already been implemented ( that is, if the parent class is not loaded to load the parent class ). Since the static {} parent class method to perform first, which means the parent class static variable takes precedence over the static variable subclass assignment.

  For instance variables, when the object is instantiated, the JVM will be allocated on the heap enough space for the object, and then the space is cleared (i.e., all types of default values assigned reference types to null). JVM will collect class copy constructor statement put in execution, if not explicitly declared constructor will generate a default constructor. Subclass generated default constructor first row default Super (); i.e., if the parent class constructor argument absence, subclasses constructor call and then call the parent class constructor to itself. Because it inherits the parent class members to use, you must initialize these members. If the parent class constructor with no arguments is not the subclass inherits will complain, need to subclass an explicit call to have the super-arg constructor of the parent class. If the class explicitly defined in one or more constructors, it is no longer generated default constructor.

  For static variables, the above description also less accurate. Class initialization phase, the JVM to ensure the same class is only performed once static {} method, which is the core of the internal static singleton class. JVM by the fully qualified class name of the class and the class loader to load it to uniquely identify a class. ( This is very important, there is often this aspect of the pit! For example, when deserialized, serialized java objects using the default class loader, using a framework deserialization party use (such as springBoot have their own the class loader) impose its own class loader to load a class, because the JVM will not determine a category and report ClassNotFoundException! )

  So what correction is to say, the core principle of the internal static singleton class for a class, JVM when only one class loader to load it, the assignment of static variables only once in the Global!

  The advantage of using a static inner classes are: Class because the external reference to a passive internal reference class, does not belong to the aforementioned three kinds of cases must be initialized, the loaded class itself does not need to load classes inside the same time. Examples of such need is triggered only within the class to load and instantiate this class, so that the delay loading (lazy loading), to save memory. At the same time because the JVM will ensure that <cinit> () method (Method initialize) a class during execution of the security thread, thus ensuring the uniqueness of global instances.

  Now we come to realize what a singleton static inner classes:

/ ** 
* @author the Nyr 
* @date 2019/11/19 20:48 
* @Description singleton - static inner class way 
* / 
public  class Car2 {
     Private Car2 () {} 

    Private  static  class innerCar2 {
         Private  static Car2 CAR2 = new new Car2 (); 
    } 
    
    public Car2 getCar2 () {
         return innerCar2.car2; 
    } 
}

 

  Why inner class instead of using static variables, I felt for two reasons (demand correction, the second is not quite sure, the subsequent write test code):

  1. Delay internal class can be loaded. If the direct use of static variables, for other reasons, such as for instance load subclass has been initialized, but this time do not need instances of the class, resulting in a waste of resources.

  2. Since the original class with a business meaning, in use have a variety of ways, such as using a specific class loader to load, thus causing damage to a single embodiment.

  Then we come to talk about the advantages of disadvantage that mass participation within the class is not very flexible, you need to define the parameters for the final. Of course, we can write Object array or a final receiving init parameters inside the class definition () method to receive parameters , but in general parameter passing really inconvenient.

  And a pair of said DCL, a sync block used significantly reduces the efficiency. Both methods can be said to have their own advantages and disadvantages, depending on the actual situation we should select as appropriate.

 

Guess you like

Origin www.cnblogs.com/niuyourou/p/11892617.html