Singleton mode

Singleton Pattern is one of the simplest design patterns in Java. This type of design pattern is a creative model that provides the best way to create objects.

This pattern involves a single class that is responsible for creating your own objects while ensuring that only a single object is created. This class provides a way to access its unique object, which can be accessed directly without the need to instantiate an object of that class.

Note:

  • 1, a singleton class can only have one instance.
  • 2, the singleton class must create its own unique instance.
  • 3. The singleton class must provide this instance to all other objects.

Introduction

Intent: Ensure that a class has only one instance and provides a global access point to access it.

Main solution: A globally used class is frequently created and destroyed.

When to use: When you want to control the number of instances and save system resources.

How to solve: Determine if the system already has this singleton, if it is, return it, if not, create it.

Key Code: The constructor is private.

Application example: 1. A party can only have one secretary. 2, Windows is multi-process multi-threaded, when operating a file, it is inevitable that multiple processes or threads operate a file at the same time, so all files must be processed through a unique instance. 3, some device managers are often designed as a single-case mode, such as a computer with two printers, the output must be processed when two printers can not print the same file.

Advantages: 1, there is only one instance in memory, reducing the memory overhead, especially the frequent creation and destruction of instances (such as the management college home page cache). 2. Avoid multiple occupations of resources (such as writing file operations).

Disadvantages: There is no interface, no inheritance, and conflict with a single responsibility principle. A class should only care about internal logic, not care about how it is instantiated outside.

Usage scenarios: 1. Request to produce a unique serial number. 2, the counter in the WEB, do not need to be added once in the database every time you refresh, use a single case to cache first. 3. An object created needs to consume too many resources, such as the connection of I/O to the database.

Note: The getInstance() method needs to use the synchronous lock synchronized (Singleton.class) to prevent multiple threads from entering at the same time, causing the instance to be instantiated multiple times.

Implementation

We will create a SingleObject class. The SingleObject class has its private constructor and a static instance of itself.

The

SingleObject class provides a static method for the outside world to get its static instance. SingletonPatternDemo, our demo class uses the SingleObject class to get the SingleObject object.

singleton pattern uml diagram

Step 1

Create a Singleton class.

SingleObject.java

public class SingleObject { //Create an object for SingleObject< /span> private static SingleObject instance = new SingleObject(); //Let the constructor be private so that the class will not be instantiated< Span class="hl-comment"> private SingleObject(){} //Get the only available object< /span> public static SingleObject getInstance(){ return instance; } public void showMessage(){ System.out< Span class="hl-code">.println("Hello World!"); } }

Step 2

Get a unique object from the singleton class.

SingletonPatternDemo.java

public class SingletonPatternDemo { public static void main(String[] args) { //Illegal constructor< /span> //Compile-time error: The constructor SingleObject() is invisible //SingleObject object = new SingleObject(); //Get the only available object< /span> SingleObject object = SingleObject.getInstance(); //Show messages object.showMessage< Span class="hl-brackets">(); } }

Step 3

Executing the program, outputting results:

Several implementations of singleton mode

The singleton mode is implemented in a number of ways, as follows:

1, lazy, thread is not safe

Is Lazy Initialization:Yes

Do you have multi-threaded security:No

Implementation difficulty:easy

Description: This method is the most basic implementation. The biggest problem with this implementation is that it does not support multithreading. Because there is no lock synchronized, it is not a singleton mode in the strict sense.
This way lazy loading is obvious, does not require thread safety, and does not work properly in multithreading.

Instance

public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new< Span class="hl-code"> Singleton(); } return instance; } }

There are several implementations that are described below that support multithreading, but differ in performance.

2, lazy, thread safe

Is Lazy Initialization:Yes

Do you have multi-threaded security:Yes

Implementation difficulty:easy

Description: This method has good lazy loading and works well in multithreading, but it is very inefficient and does not require synchronization in 99% of cases.
Advantages: Initialize the first call to avoid wasting memory.
Disadvantages: You must lock synchronized to guarantee a singleton, but locking will affect efficiency.
The performance of getInstance() is not critical to the application (this method is used less frequently).

Instance

public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance( ) { if (instance == null) { instance = new< Span class="hl-code"> Singleton(); } return instance; } }

3, hungry Chinese style

Is Lazy Initialization:No

Do you have multi-threaded security:Yes

Implementation difficulty:easy

Description: This method is more common, but it is easy to generate garbage objects.
Advantages: Without locking, execution efficiency will increase.
Disadvantages: The class is initialized when it is loaded, wasting memory.
It avoids multi-thread synchronization problems based on the classloader mechanism. However, instance is instantiated when the class is loaded. Although there are many reasons for class loading, most of the singleton mode calls the getInstance method, but it is not certain. There are other ways (or other static methods) that cause the class to load. At this point, the initialization instance obviously does not achieve the effect of lazy loading.

Instance

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

4, double check lock / double check lock (DCL, double-checked locking)

JDK version:From JDK1.5

Is Lazy Initialization:Yes

Do you have multi-threaded security:Yes

Implementation difficulty: More complicated

Description: This approach uses a double-lock mechanism that is secure and maintains high performance in multi-threaded situations.
The performance of getInstance() is critical to the application.

Instance

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< Span class="hl-code"> Singleton(); } } } return singleton; } }

5, registered/static inner class

Is Lazy Initialization:Yes

Do you have multi-threaded security:Yes

Implementation difficulty:General

Description: This method can achieve the same effect as the double check lock method, but the implementation is simpler. Use lazy initialization for static domains, which should be used instead of double-checking. This method is only applicable to static domain situations, and the double check lock mode can be used when the instance domain requires delayed initialization.
This method also uses the classloader mechanism to ensure that there is only one thread when initializing the instance. It differs from the third method in that: In the third way, as long as the Singleton class is loaded, the instance will be instantiated (the lazy loading is not reached). Effect), and this way the Singleton class is loaded, and the instance is not necessarily initialized. Because the SingletonHolder class is not actively used, the instance is instantiated only by explicitly loading the SingletonHolder class when the getInstance method is explicitly called. Imagine if instantiating an instance is very resource intensive, so I want it to be lazily loaded. On the other hand, I don't want to instantiate it when the Singleton class is loaded, because I can't guarantee that the Singleton class might be actively used elsewhere. Loading, then instantiating the instance at this time is obviously not appropriate. At this time, this method is quite reasonable compared to the third method.

Instance

public class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance( ) { return SingletonHolder.INSTANCE; } }

6, enumeration

JDK version:From JDK1.5

Is Lazy Initialization:No

Do you have multi-threaded security:Yes

Implementation difficulty:easy

Description: This implementation has not been widely adopted, but it is the best way to implement the singleton pattern. It is more concise and automatically supports serialization mechanisms, absolutely preventing multiple instantiations.
This approach is advocated by Effective Java author Josh Bloch, which not only avoids multi-threaded synchronization issues, but also automatically supports serialization mechanisms to prevent deserialization from recreating new objects and absolutely preventing multiple instantiations. However, since the enum feature was added after JDK1.5, writing in this way is inevitably unfamiliar, and is rarely used in practical work.
Private constructors cannot be called with reflection attack.






javacodegeeks is optimized for learning.© javacodegeeks .
All Right Reserved and you agree to have read and accepted our term and condition