GOF Design Mode 1: Singleton design mode, gof Design Mode
1. core functions of the singleton design model:
Ensure that a class has only one instance and provides global access points for this instance.
2. Common application scenarios:
- Job Manager of window
- Reading configuration files in a project is also a singleton mode.
- The database connection pool is also designed in the singleton mode because database connection is a type of database resource.
- The file management system of the operating system is also a singleton mode. An operating system can only have one File System
- Application is also a singleton Application (Servlet programming or Android Application class)
- In Spring, each bean is also a singleton by default. This is a bit of a thing that Spring containers can manage.
- In Servlet programming, each Servlet is also a singleton.
- In Spring MVC and Struts1, the Controller object is also a singleton.
3. Advantages of Singleton Mode
- Because the singleton mode only produces one object, the system overhead is reduced. When an object requires a large amount of resources, such as reading the configuration file and generating other dependent objects, you can directly generate a singleton object when the application is started, and then store the memory permanently.
- In Singleton mode, you can set global access points in the system to optimize access to shared resources. For example, you can design a singleton class to map all data tables.
4. Common 5 implementation methods of the single-instance mode:
Main
Ele. Me: thread security and high calling efficiency. But it cannot be loaded in a delayed manner.
Lazy style: thread security, low call efficiency. However, loading can be delayed.
Others:
Double lock check: Due to the underlying JVM internal model, occasional problems may occur, and it is not recommended to use
Static internal class: thread security, high call efficiency, and delayed Loading
Enumeration singleton: thread security, high call efficiency, and non-delayed Loading
Sample Code of the hungry Chinese style:
Public class Singleton01 {// This object is loaded immediately when the class is initialized (without the advantage of delayed loading ). When a class is loaded, it is a thread-safe private static Singleton01 instance = new Singleton01 (); private Singleton01 () {}// The method does not have synchronous call efficiency high public static Singleton01 getInstance () {return instance ;}}
In the code of the hungry Chinese Singleton mode, the static variable will be initialized during class loading, so that multiple thread objects will not be involved in accessing the object. The virtual opportunity ensures that the class is loaded only once, so concurrent access will not occur. Therefore, the synchronized keyword can be omitted.
Problem: If you only load this class, instead of calling getInstance, or even never call it, it will cause a waste of resources.
Lazy sample code
1 package com. chunjiangchao. pattern. singleton; 2/** 3 * test the lazy singleton Mode 4 */5 public class Singleton02 {6 // This object is not initialized during class initialization (delayed loading, ). 7 private static Singleton02 instance = null; 8 private Singleton02 () {} 9 // method synchronization, low call efficiency! 10 public static synchronized Singleton02 getInstance () {11 if (instance = null) 12 instance = new Singleton02 (); 13 return instance; 14} 15}
Key Point: delayed loading. loading is selected only when lazy loading is actually used.
Problem:
High resource utilization, but synchronization is required for every call to the getInstance () method, resulting in low concurrency efficiency.
Dual lock check implementation
1 package com. chunjiangchao. pattern. singleton; 2/** 3 * test DCL (dual lock check) singleton Mode 4*5 */6 public class Singleton03 {7 // when the class is initialized, do not initialize this object (delayed loading, which can be created when actually used ). 8 private volatile static Singleton03 instance = null; 9 private Singleton03 () {} 10 // code block synchronization, the call efficiency is faster than the synchronization method, due to JVM, problems may occur in high concurrency. 11 public static Singleton03 getInstance () {12 if (instance = null) {13 synchronized (Singleton03.class) {14 if (instance = null) 15 instance = new Singleton03 (); 16} 17} 18 return instance; 19} 20}
This improves the execution efficiency. You do not have to synchronize the object every time you obtain it. Only the first time you create the object, you can create the object synchronously.
Problem:
Occasionally, problems may occur due to compiler optimization and underlying JVM internal models. We do not recommend this feature. However, you can add the volatile keyword before the instance.
Static internal class implementation method: (lazy loading method)
1 package com. chunjiangchao. pattern. singleton; 2/** 3 * static internal class singleton Mode 4 * This mode: thread security, high call efficiency, and delayed loading! 5 */6 public class Singleton04 {7 private Singleton04 () {} 8 public static Singleton04 getInstance () {9 return Inner. instance; 10} 11 private static class Inner {12 private static final Singleton04 instance = new Singleton04 (); 13} 14}
If the external class does not have the static attribute, it will not create the object as it is in the hungry Chinese style.
Only the real call to getInstance will load static internal classes. It is thread-safe to load classes. The instance is of the static final type, ensuring that only such an instance exists in the memory and is assigned only once, thus ensuring thread security.
The advantages of concurrent and efficient calls and delayed loading of mergers.
Another user said: static internal systems have the advantages of hungry and delayed loading.
Enumeration implementation example:
1 package com. chunjiangchao. pattern. singleton; 2/** 3 * enumeration Implementation of singleton mode (without delay loading) 4 */5 public enum Singleton05 {6 instance; // This enumeration element, itself is a singleton object! 7 public void operation () {8 // Add required operation 9} 10}
Advantages: simple implementation; enumeration itself is a singleton. It is fundamentally guaranteed by JVM. Avoid reflection and serialization Vulnerabilities
Disadvantage: no delay Loading
5. How to choose these five Singleton modes?
The single-instance object consumes less resources and does not require delayed loading:
Enumeration is better than the hungry Chinese type
A single-instance object occupies a large amount of resources and requires delayed loading.
Static internal class is better than lazy class
6. Problems
Reflection can crack the above (excluding enumeration) implementation method (the prevention is to manually throw an exception in the constructor)
Deserialization can crack (excluding enumeration) Implementations
You can define readResolve to prevent different objects from being obtained. During deserialization, if the class of the object defines the readResolve () method (a callback method), the object created by the user is returned.