1、什么是单列模式
单列模式(Singleton)保证一个类仅有一个实例,并提供一个访问的全局访问点,这种类型的设计模式属于创建型模式。在开发中,会经常遇到一个全局使用的类频繁地创建与销毁,这会非常浪费系统的内存资源,而且容易导致错误甚至一定会产生错误,所以我们单例模式所期待的目标或者说使用它的目的,是为了尽可能的节约内存空间,减少无谓的GC消耗,并且使应用可以正常运作。
结构图
2、实现方式
2.1、懒汉模式,线程不安全
最基本的实现方式,这种实现最大的问题就是不支持多线程。
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
针对懒汉模式线程不安全的问题,我们自然想到了,在getInstance()方法前加锁,于是就有了第二种实现
2.2、懒汉模式,线程安全
能够在多线程中很好的工作,打补丁方式写出来的结构效率很低,多数情况下不需要同步。
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
因为加了synchronized为独占排他锁,并发性能差,于是为了解决这个问题又有第三种实现
2.3、饿汉式
在类加载的时候,就完成了对象的初始化,类加载保证了他们天生是线程安全的
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
没有达到Lazy Loading的效果,如果从始至终从未使用过这个实例,则会造成内存的浪费,那如何解决这个问题呢?
2.4、静态内部类
Singleton 类被装载了,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;
}
}
2.5、枚举
枚举实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化和线程安全的
public enum Singleton {
INSTANCE;
public void action() {
}
}
调用
Singleton.INSTANCE.action();
2.6、双重校验锁法
采用双锁机制,安全且在多线程情况下能保持高性能
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 Singleton();
}
}
}
return singleton;
}
}
3、总结
推荐使用3-6的实现方式,当然并不是说1-2不能使用,具体的还需要根据业务场景来使用,例如不需要再多线程使用的可以根据1来实现;需要支持序列化的可以使用5来实现,一般情况下建议使用3来实现
网友评论