设计模式:Singleton(单例模式)--创建型模式
一、介绍
一个类有且仅有一个全局实例,并且提供一个访它的全局访问点。单例模式让自身保存自己的唯一实例,使得这个类保证没有其他实例可以被创建,从而提供一个访问该实例的方法。
二、适用性
- 当类只能有一个实例,且客户可以从一个众所周知的访问点访问它时
- 当这个唯一实例应该是通过子类可扩张的,并且客户应该无需更改代码就能够使用一个扩展的实例时
三、参与者
Singleton
定义一个instance操作,允许客户访问他的唯一实例,Instance是一个类操作,它可能负责创建他自己的唯一实例。
四、效果
对唯一实例的受控访问:Singleton类封装他的唯一实例,所以它可以严格的控制客户怎么样访问他。
缩小名字空间:singleton 模式是对全局变量的一种改进,避免了存储唯一实例的全局变量污染名字空间。
允许对操作和表示的精化: Singleton可以有子类,并且用这个扩展类的实例来配置一个应用是很容易的
允许可变数目的实例
比类操作更灵活
五、实现
懒汉模式
public class Singletion {
private static Singletion instance;
private Singletion(){}
public static Singletion getInstance(){
if(instance == null){
instance = new Singletion();
}
return instance;
}
}
懒汉模式中单例被延迟加载,只有真正在使用的时候才会实例化一个对象并交给自己引用。
优:、
延迟加载,只有真正使用的时候才会实例化
缺:
多线程下不安全,可能会产生多个实例,在多线程下不能使用这种方式
饿汉模式
public class Singletion1 {
private static Singletion1 instance = new Singletion1();
private Singletion1(){}
public static Singletion1 getInstance(){
return instance;
}
}
饿汉模式在类被加载时候,就会进行实例化对象,并交给自己的引用,而在整个生命周期中一直存在。
优:
类加载时完成初始化实例,避免线程同步问题
缺:
由于实例化一次后一直存在,如果之后没有使用这个实例,会造成内存的浪费
双重锁
public class Singletion2 {
private volatile static Singletion2 instance;
private Singletion2(){}
public static Singletion2 getInstance(){
if (instance == null ){
synchronized (Singletion2.class){
if (instance == null){
instance = new Singletion2();
}
}
}
return instance;
}
}
双重锁中进行两次的instance == null的判断,这样实例化代码只执行一次,再次访问时候,直接return
优:
线程安全、延迟加载、效率高(会消耗一点性能,但更加稳定)
内部类
public class Singletion3 {
private Singletion3(){}
public static Singletion3 getInstance(){
return Inner.instance;
}
private static class Inner{
private static final Singletion3 instance = new Singletion3();
}
}
只有在第一次调用getInstance方法时候,虚拟机才加载Inner并且初始化instance;只有一个线程能够获得初始化,保证对象的唯一性。在较多的地方推荐使用。
标题:设计模式:Singleton(单例模式)--创建型模式
作者:sirwsl
地址:https://www.wslhome.top/articles/2020/07/28/1595927146159.html