1.简介
保证一个类仅有一个实例(防止实例化多个对象),且提供一个访问它的全局访问点。可以严格的控制客户怎么访问它,何时访问它。
它与静态工具类的不同点:
- 静态工具类不保存状态,仅提供静态方法与静态属性
- 静态工具类不能用于继承
- 静态工具类是方法属性的集合,单例类有着唯一的对象实例
- 减少JVM对于new的消耗
2.如何实现?
- 私有构造
- 提供全局访问点
- 内部构建函数
3.实现方式
- 懒汉式,非线程安全:延时初始化,非线程安全
public class Singleton {
private static Singleton instance;
// 私有构造
private Singleton(){}
// 全局访问点
public static Singleton getInstance(){
if (instance==null) {
instance = new Singleton();
}
return instance;
}
}
- 懒汉式,线程安全:延时初始化,线程安全
加锁,效率低下
public class Singleton {
private static Singleton instance;
// 私有构造
private Singleton(){}
// 全局访问点
public static synchronized Singleton getInstance(){
if (instance==null) {
instance = new Singleton();
}
return instance;
}
}
- 饿汉式,线程安全:非延时初始化,线程安全
类加载时就初始化,浪费内存易产生垃圾对象。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
- 双检锁/双重校验锁(DCL,即 double-checked locking):延时初始化,线程安全
采用双锁机制,安全并且在多线程下能有较高的效率。
public class Singleton {
private volatile static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
- 登记式/静态内部类:延时初始化,线程安全
这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。第 3 种方式只要 Singleton 类被装载了,那么 instance 就会被实例化(没有达到 lazy loading 效果),而这种方式是 Singleton 类被装载了,instance 不一定被初始化。因为 SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance。
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
- 枚举:非延时初始化,线程安全
这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。
public enum Singleton {
INSTANCE;
public void method(){
}
}
使用:Singleton.INSTANCE.method();
使用注意:
- 不建议使用懒汉模式,建议使用饿汉模式;
- 明确要求延时加载时使用登记式;
- 枚举以及双检锁方式看需求选取;
参考:https://www.runoob.com/design-pattern/singleton-pattern.html