面试篇(基础):单例模式(Singleton)
单例模式定义
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。
每台计算机可以有若干个打印机,但只能有一个 Printer Spooler,以避免两个打印作业同时输出到打印中。
每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。
总之,选择单例模式就是为了避免不一致状态。
单例模式的特点
➢ 单例类只能有一个实例。
➢ 单例类必须自己创建自己的唯一实例。
➢ 单例类必须给所有其他对象提供这一实例。
单例模式保证了全局对象的唯一性,比如系统启动读取配置文件就需要单例保证配置的一致性
单例的四大原则
➢构造私有
➢以静态方法或者枚举返回实例
➢确保实例只有一个,尤其是多线程环境
➢确保反序列话时不会重新构建对象
实现单例模式的方式
1.饿汉式(立即加载)
饿汉式单例在类加载初始化时就创建好一个静态的对象供外部使用。
除非系统重启,这个对象不会改变,所以本身就是线程安全的。
public class SingletonHugry {
public SingletonHugry() { }
private static SingletonHugry single = new SingletonHugry();
public static SingletonHugry getInstance() {
return single;
}
public static void main(String[] args) {
SingletonHugry instance = SingletonHugry.getInstance();
}
}
存在的问题
在没有使用这个对象的情况下就加载到内存是一种很大的浪费。
针对这种情况,有一种新的思想提出——延迟加载,也就是所谓的懒汉式。
2.懒汉式(延迟加载)
该示例在调用getInstance()时才会创建对象,起到了延迟加载的作用。
但在多线程环境下会产生多个 Singleton 对象,存在线程安全问题。
public class SingletonLazy {
public SingletonLazy() {}
private static SingletonLazy single = null;
public static SingletonLazy getInstance() {
if (single == null){
single = new SingletonLazy();
}
return single;
}
public static void main(String[] args) {
SingletonHugry instance = SingletonHugry.getInstance();
}
}
3.同步锁(解决线程安全问题)
在方法上加 synchronized 同步锁或是用同步代码块对类加同步锁。
此种方式虽然解决了多个实例对象问题,但是该方式运行效率却很低下。
下一个线程想要获取对象,就必须等待上一个线程释放锁之后,才可以继续运行。
public class Singleton {
private Singleton() { }
private static Singleton single = null;
public static synchronized Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
Other
此外,还有双重检查锁(提高同步锁的效率)和静态内部类等等可以实现 ...
版权声明:
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
Yida!
喜欢就支持一下吧