- The singleton pattern (Singleton Pattern) is one of the simplest design patterns in Java. This type of design pattern is a creational pattern that provides the best way for common objects.
-
This pattern involves a single class, which is responsible for creating its own objects, while ensuring that only a single object is created. This class provides a way to access its only objects, which can be accessed directly without instantiating objects of this 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;
-
-
Intent: To ensure that there is only one instance of a class, and to provide 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 instance trees and save system resources;
-
How to solve: judge whether the system already has this singleton, return if there is, create if not;
-
Key code: The constructor is private;
-
Applications:
-
-
1. There is only one teacher in a class;
-
2. WIndows is multi-process and multi-thread. When operating a file, it is inevitable that multiple processes or threads operate on a file at the same time, so all files must be processed through a unique instance;
-
3. Some device managers are often designed in singleton mode, for example, a computer has two printers, and it is necessary to deal with the problem that two printers cannot print the same file when outputting;
-
-
advantage:
-
-
1. There is only one instance in memory to reduce memory overhead, especially frequent creation and destruction of instances (such as WEB page cache);
-
2. Avoid multiple possession of resources (such as file writing operations);
-
-
Disadvantages: There is no excuse, it cannot be inherited, and it conflicts with the principle of single responsibility. A class should only care about internal logic, not how it is instantiated outside;
-
scenes to be used:
-
-
1. Require the production of a unique serial number;
-
2. The counter in WEB does not need to be added to the database every time it is refreshed, and it is cached first with a single case;
-
3. To create an object consumes too many resources, such as the connection of I / O to the database, etc .;
-
Note: The getInstance () method needs to use synchronized lock synchronized (Singleton.class) to prevent multiple threads from entering at the same time and causing the Instance to be instantiated multiple times;
-
-
Actual combat:
-
-
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 obtain its static instance.
-
package singleton;
/**
* @author yangxin_ryan
*/
public class SingleObject {
// Create singleObject Object
private static SingleObject instance = new SingleObject();
// make construct private avoid instatiation
private SingleObject(){}
public static SingleObject getInstance(){
return instance;
}
public void showMessage() {
System.out.println("Hello World!");
}
}
package singleton;
/**
* @author yangxin_ryan
*/
public class SingletonPatternDemo {
public static void main(String[] args) {
SingleObject object = SingleObject.getInstance();
object.showMessage();
}
}
- The remaining implementation versions
package singleton;
/**
* @author yangxin_ryan
* 懒汉式,线程不安全
* 这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程,因为没有加锁synchronized,所以严格意义上并不算单例模式;
*/
public class SingletObject1 {
private static SingletObject1 instance;
private SingletObject1() {}
public static SingletObject1 getInstance(){
if (instance == null) {
instance = new SingletObject1();
}
return instance;
}
}
package singleton;
/**
* @author yangxin_ryan
* 懒汉式,线程安全
* 这种方式具备很好的lazy loading,能够在多线程中很好的工作,但是效率很低,99%情况下不需要同步;
*/
public class SingletObject2 {
private static SingletObject2 instance;
private SingletObject2() {}
public static synchronized SingletObject2 getInstance(){
if (instance == null) {
instance = new SingletObject2();
}
return instance;
}
}
package singleton;
/**
* @author yangxin_ryan
* 饿汉式,线程安全
* 这种方式比较常见,但容易产生垃圾对象。它基于classloader机制避免了多线程的同步,不过instance在类装载时就实例化,
* 虽然导致类装载的原因有很多,在单例模式中大多数都是调用getInstance方法,但是也不能确定有其他的方式(或者其他静态方法)导致类加载。
* 这时候初始化intance显然没有达到lazy loading效果
*/
public class SingletObject3 {
private static SingletObject3 instance = new SingletObject3();
private SingletObject3(){}
public static SingletObject3 getInstance(){
return instance;
}
}
package singleton;
/**
* @author yangxin_ryan
* 双检索/双重校验锁,线程安全
* 这种方式采用双锁机制,安全且在多线程情况下能保持高性能
*/
public class SingletObject4 {
private volatile static SingletObject4 singleton;
private SingletObject4(){}
public static SingletObject4 getInstance() {
if (singleton == null) {
synchronized (SingletObject4.class) {
if (singleton == null) {
singleton = new SingletObject4();
}
}
}
return singleton;
}
}