一、单例模式定义:
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
二、实现方式:
懒汉模式
public class Demo {
// 1、私有构造函数
private Demo() {}
// 2、单例实例
private static Demo instance = null;
// 3、获取实例接口
public static Demo getInstance() {
if(instance == null) {
synchronized(Demo.class) {
if(instance == null) {
instance = new Demo();
}
}
}
return instance;
}
}
评价:延时加载,节约了内存。效率相对低一些。利用同步块实现线程安全。
饿汉模式
public class Singletion {
private Singletion() {}
private static Singletion instance = new Singletion(); // Singletion类加载的时候,就初始化这个实例
public static Singletion getInstance() {
return instance;
}
}
评价:程序启动时加载,先加载类,再初始化静态属性,由于后面无法再对对象进行修改,从而实现线程安全,效率相对高一些。占用内存相对多一些。
IoDH技术实现单例模式(静态内部类)
public class Singletion {
private Singletion () {}
private static class InnerSingletion {
private static Singletion single = new Singletion();
}
public static Singletion getInstance(){
return InnerSingletion.single;
}
}
评价:使用静态内部类的方式,只有在使用该实例的时候,才去加载静态内部类,从而实现延时加载。因为静态内部类只初始化一次,静态内部类的静态属性也只初始化一次,后面无法修改对象的状态,从而实现线程安全。综合了上述两种方法的优点。
三、单例模式的优缺点:
(1)单例模式没有抽象层,因此单例模式的扩展比较困难的。
(2)单例类的职责过重,一定程度上违背了“单一职责原则”。
(3)长时间不使用的单例类可能被系统回收,导致单例对象状态的丢失。