单例模式
Demo地址
https://github.com/rocky123shine/instance
单例
1.概念
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例
2.使用的目的
单例模式可以有效的控制对象的创建(保证只有一个对象),节约内存开销,提高效率(性能),提高资源使用率。
3.特点
1)私有化构造方法
2)提供静态方法来提供当前类的对象
3)对象只有一个
4)确保在序列化和反序列化的过程中是同一个对象
5)单例类不允许被继承
常用单例模式种类
1.恶汉式
特点:类创建的同时实例化对象 不管有没有用到该类的对象
public class Singleton {
//这种实例化的方式 内存消耗
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
//直接实例化 不会出现为空的情况
return instance;
}
}
2.懒汉式
特点:类创建的同时不实例化,需要的时候在创建
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
//这样实例化的有点是可以一定层度减少内存开销
//但是有多线程的问题 并发的时候 创建多个
if (instance == null) {
instance = new Singleton();
//此处是需要的时候才检查 是否有实例化
}
return instance;
}
}
3.双重校验
特点:类创建的同时不创建对象,用到的时候双重检查,并且加锁保证了线程安全
3.1双重校验原始版
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
//第一次检查
if (instance == null) {
//同步代码快 枷锁
synchronized (Singleton.class) {
//第二次检查
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
3.2双重校验改进版
//分析编译器编译过程
//Singleton instance = new Singleton()
//这句代码的意义是实例化一个对象
// 那么他的执行顺序是 new 开辟空间(分配内存)(1)–> 调用构造函数 初始化参数(2)–>将instance 对象 指向这块内存空间(3)
//在jvm 1.5之前 cash 寄存器 顺序可能是 1-2-3 有可能是 1-3-2 区别在于 是不是先初始化数据在指向内存 还是先指向空内存 在初始化
//此时 为了解决这个问题 引入了volatile 。使用没有进行优化过编译器或者共享内存处理器,正常运行
//volatile含义:去掉虚拟机优化代码到主内存回写顺序可能会乱序
private static volatile Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
//第一次检查
if (instance == null) {
//同步代码快 枷锁
synchronized (Singleton.class) {
//第二次检查
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
4.静态内部类(官方推荐版)
特点:创建类的同时内部静态类创建,内部静态类的静态成员初始化,既能够保证内存优化,同时也能够保证安全
public class Singleton {
private Singleton(){
}
public static Singleton getInstance(){
return SingletonHolder.singleton;
}
public static class SingletonHolder {
private static Singleton singleton = new Singleton();
}
}
5.枚举
特点:枚举高级使用
public enum Singleton {
instance;
}
6.集合方法-对象管理
特点:创建一个单例类的同时 创建一个对象管理类,对象管理类中维护一个map,保证了对象只有一个
public class Singleton {
...
}
public class ObjectManager {
private Map<String,Singleton> map;
public ObjectManager(){
map = new HashMap<>();
}
public void putObject(String key,Singleton singleton){
Singleton singleton1 = map.get(key);
if (singleton1==null) {
//保证只有一个对象
map.put(key,singleton);
}
}
}