Several implementations of the Java singleton pattern

       In the usual work, student learning and interview process, the singleton pattern, as a commonly used design pattern, is often asked by the interviewer, and even the written test will require the students to dictate on the spot. The following will discuss the implementation of the singleton pattern. Simple sharing with several common implementations.

Singleton pattern is a commonly used software design pattern. In its core structure it contains only a special class called a singleton. The singleton pattern can ensure that in the system, a class that applies this pattern has only one instance of a class. That is, a class has only one object instance. It is one of the most commonly used design patterns, and friends who are familiar with design patterns will not be unfamiliar with the singleton pattern. Generally, books that introduce the singleton pattern will mention  two implementations: hungry  and lazy . But in addition to these two ways, this article will also introduce several other ways to implement singletons.  

Basic realization ideas

  The singleton pattern requires the class to have a reference to the returned object ( always the same one ) and a method to get the instance (must be a static method, usually using the name getInstance ).

In layman's terms: that is, to design a class, there is only one object in the entire application (it needs to be done so that the outside of this class cannot create objects at will)

The implementation of a singleton is mainly through the following three steps:

① Constructor privatization (reflection is not considered for the time being)

② Create an object internally and save it

③ Provide a public static method to return the address of the internal object

 

The first implementation method: the hungry Chinese style [ static constant ] method

 

Sample code:

package cn.itsource.sington;

/**

 * Hungry Chinese [static constant]

 *

 * @author Administrator

 *

 */

public class SingletonTest1 {

/**

 * Singleton pattern design a class, so that there is only one instance of the object in this class

 *

 * 1 requires a private constructor, which avoids external creation of objects

 */

private SingletonTest1() {

}

/*

 * 2 Create an object inside this class and save it

 */

private static SingletonTest1 instance = new SingletonTest1();

 

/*

 * 3 Publish a public static method to return the object saved internally

 *

 */

public static SingletonTest1 getInstance() {

return instance;

}

}

 

Advantages: This way of writing is relatively simple, that is, the instantiation is completed when the class is loaded. Avoids thread synchronization problems.

Disadvantages: When the object is created when the class is loaded, it may cause the class to be loaded very slowly and not achieve the effect of Lazy Loading . If the instance is never used from beginning to end, it will cause a waste of memory.

 

The second implementation method: the hungry Chinese style [ static code block ] method

 

Sample code:

package cn.itsource.sington;

public class SingletonTest3 {

private SingletonTest3() {

}

private static SingletonTest3 instance;

static {

instance = new SingletonTest3();

}

public static SingletonTest3 getInstance() {

return instance;

}

}

 

This method is similar to the above method, except that the class instantiation process is placed in the static code block, and when the class is loaded, the code in the static code block is executed to initialize the instance of the class. The pros and cons are the same as above.

The third way to implement: the lazy [ double-checked ] way

 

Sample code:

package cn.itsource.sington;

/**

 * Lazy

 * @author Administrator

 */

public class SingletonTest2 {

/**

 * Requirement: Design a class in the singleton pattern so that there is only one instance of the object in this class

 *

 * 1 requires a private constructor, which avoids external creation of objects

 */

private SingletonTest2() {

 

}

/*

 * 2 When the class is loaded into the memory, the object does not yet exist, only when the getInstance() method is called, the

Elephant just started

 */

private static SingletonTest2 instance;

/*

 * 3 Publish a public static method to return the object saved internally

 * The lazy style is lazy loading. If multiple threads operate the lazy style at the same time, there may be thread safety problems.

To solve thread safety issues:

         It can be solved by adding synchronization. However, after synchronization is added, the lock is compared every time, and the efficiency becomes slower.

         Therefore, double judgment can be added to improve the efficiency of the program.

 */

public static SingletonTest2 getInstance() {

if (instance == null) {

synchronized (SingletonTest2.class) {

if (instance == null) {

instance = new SingletonTest2();

}

}

}

return instance;

}

}

 

Double judgment is not unfamiliar to multi-threaded developers. As shown in the code, we perform two if (instance == null) checks to ensure thread safety. In this way, the instantiation code only needs to be executed once, and when it is accessed again later, it is judged if (instance == null) , and the instantiated object is returned directly .

Advantages: thread safety; lazy loading; high efficiency.

 

The difference between hungry and lazy:

1 Hungry style is that the object is created as soon as the class is loaded into memory;

2 The lazy type is that when the class is loaded into the memory, the object does not yet exist, and the object starts to be created only when the getInstance() method is called.

3 The lazy style is lazy loading. If multiple threads operate the lazy style at the same time, there may be thread safety problems. To solve the thread safety problem, synchronization can be added. However, after synchronization is added, the lock is compared every time, and the efficiency becomes slower, so double judgment can be added to improve the program efficiency.

 

The fourth implementation method: the way of enumeration

Sample code:

package cn.itsource.sington;

public enum SingletonTest4 {

    INSTANCE;

}

The singleton pattern is implemented with the help of enumerations added in JDK1.5 . Not only does it avoid multi-thread synchronization problems, but it also prevents deserialization from recreating new objects. It may be because enumeration was added in JDK1.5 , so in actual project development, few people have written it like this.

Advantages : simple writing is its biggest advantage , and secondly, it can handle serialization by itself, which is thread-safe

Disadvantage : When you want to instantiate a singleton class, you must remember to use SingletonTest4 .INSTANCE to get the object instead of new , which may cause trouble to other developers, especially when the source code is not visible.

The above are several common implementations    of the singleton pattern , and a brief summary in the teaching and learning process. I hope it will be helpful for everyone to learn the singleton pattern.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324735989&siteId=291194637
Recommended