单例设计模式

单例设计模式概述

  1. 单例设计模式:保证类在内存中只有一个对象。并提供一个访问它的全局访问点。
  2. 如何保证类在内存中只有一个对象呢?
    • 控制类的创建,不让其他类来创建本类的对象。private
    • 在本类中定义一个本类的对象。Singleton s;
    • 提供公共的访问方式。 public static Singleton getInstance(){return s}
  3. 单例模式解决的问题:可以保证一个类在内存中的对象的唯一性。必须对于多个程序使用同一个配置信息对象时,就必须保证对象的唯一性。
  4. 注意事项:
    • 不要使用单例模式存取全局变量。这违背了单列模式的用意,最好放到对应类的静态成员中。
    • 不要将数据库连接做成单例,因为一个系统可能与数据库有多个连接,并且在有连接池的情况下,应当尽可能及时释放连接。Singleton模式由于使用静态成员存储类实例,所以可能会造成资源无法及时释放。

饿汉式(单例设计模式写法) 开发用这种方式。

  1. 类一加载,就将单例初始化好了,对象想要调用,就要使用getInstance()方法
  2. 弊端:
    • 空间使用率不高
    • 类加载时实例化,意味着该类无法在程序运行过程中通过运行参数实例化,代码失去灵活性。
			//饿汉式
			class Singleton {
				//1,私有构造函数
				private Singleton(){}
				//2,创建本类对象
				private static Singleton s = new Singleton();
				//3,对外提供公共的访问方法
				public static Singleton getInstance() {
					return s;
				}
				
				public static void print() {
					System.out.println("11111111111");
				}
			}

懒汉式(单例设计模式)单例延迟加载模式

  1. 延迟加载,只是你要使用的时候才会帮你初始化单例。
  2. 弊端:
    • 容易引发线程问题,因为如果线程1访问getInstance()方法时,被迫陷入沉睡,而线程2来访问的时候并没有单例初始化,所以就会初始化单例,而恰好线程1苏醒,继续初始化单例,从而产生多个单例。
//懒汉式,单例的延迟加载模式
			class Singleton {
				//1,私有构造函数
				private Singleton(){}
				//2,声明一个本类的引用
				private static Singleton s;
				//3,对外提供公共的访问方法
				public static Singleton getInstance() {
					if(s == null)
						//线程1,线程2
						s = new Singleton();
					return s;
				}
				
				public static void print() {
					System.out.println("11111111111");
				}
			}

双重检查锁(单例设计模式)

  1. 所谓的双重检查,是在同步前后的两次if(instance == null)判断,是否已经存在实例,锁自然指的就是synchronized关键字。
  2. 对着代码,我们再来考虑两个线程同时通过了第一道if(instance == null)检查,但因为同步锁是互斥的,只能第一个线程释放后,第二个线程才能持有。这保证了同步代码块的原子性,在同步代码块中的如果instance还为创建,此时才会创建。
public class Singleton {
    private volatile static Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance(){
        //先检查实例是否存在,如果不存在才进入下面的同步块
        if(instance == null){
            //同步块,线程安全的创建实例
            synchronized (Singleton.class) {
                //再次检查实例是否存在,如果不存在才真正的创建实例
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

静态内部类

  1. 静态内部类的特点:
    * 线程安全:由静态内部类中的静态成员初始化时创建实例,通过JVM类加载机制来保证线程的安全性。
    * 懒加载:使用静态内部类的方式,让类SingletonHolder只有在使用的时候才会被加载,实例才会创建,借机实现了懒加载。
public class Singleton {
    private Singleton(){}
	// 只有当类被调用时,才会加载
    private static class SingletonHolder{
        // 静态初始化器,由JVM来保证线程安全
        private static Singleton instance = new Singleton();
    }
    
    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
}

总结

  1. 单例设计模式作为入门设计模式,还是有许多可以深究的地方,还需要努力学习。
  2. 参考文献:推荐写的非常详细
    单例设计模式详解
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值