千家信息网

设计模式--单例模式--第一天学习

发表于:2024-11-25 作者:千家信息网编辑
千家信息网最后更新 2024年11月25日,单例模式单例模式的优点:由于单例模式只生成一个实例,减少了系统性能开销,当一个对象产生需要比较多资源时,如读取配置,产生其他依赖对象时,则可以通过启动时直接产生一个单例对象,然后永久的驻留在内存的方式
千家信息网最后更新 2024年11月25日设计模式--单例模式--第一天学习

单例模式

单例模式的优点:

由于单例模式只生成一个实例,减少了系统性能开销,当一个对象产生需要比较多资源时,如读取配置,产生其他依赖对象时,则可以通过启动时直接产生一个单例对象,然后永久的驻留在内存的方式解决

单例模式的实现:

有五中方式

1. 饿汉式

2. 懒汉式

3. 双重检测锁实现

4. 静态内部类实现

5. 枚举类型实现

下边对五中类型做详细笔记

饿汉式单例模式

饿汉式特点:线程安全,调用效率高,但是不能延时加载

缺点:如果只是加载类,而不调用类中的方法,则会造成资源浪费

饿汉式实现:

1. 在定义类中定义一个静态变量,然后创建类对象赋值给静态变量,

2. 构造器要私有化

3. 定义静态方法返回静态变量

代码:

public class SingletonDemo1 {//类初始化时,立即加载这个对象(没有延时加载的优势)。加载类时,天然的是线程安全的!private static SingletonDemo1 instance = new SingletonDemo1(); private SingletonDemo1(){}//方法没有同步,调用效率高!public static SingletonDemo1  getInstance(){           return instance;}}

懒汉式单例模式

懒汉式特点:线程安全,调用效率不高,但是可以延时加载

缺点:资源利用率高了,但是每次调用getInstance()方法都要同步,并发效率低

懒汉式实现:

1. 在定义的类中定义一个私有的静态变量,不用赋值

2. 构造方法私有化

3. getInstance()方法加锁synchronized,方法中只创建一次对象,对静态变量赋一次值

代码:

public class SingletonDemo2 {//类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)。private static SingletonDemo2 instance; private SingletonDemo2(){ //私有化构造器}//方法同步,调用效率低!public static  synchronized SingletonDemo2  getInstance(){           if(instance==null){                    instance = new SingletonDemo2();           }           return instance;}}

双重检测锁实现单例

双重检测锁特点:实现了懒加载和调用效率高的特点

缺点:由于编译器优化原因和jvm底层内部模型原因,偶尔会出现问题,不建议使用

双重检测锁实现:

public class SingletonDemo3 {    private static SingletonDemo3 instance = null;    public static SingletonDemo3 getInstance() {     if (instance == null) {       SingletonDemo3 sc;       synchronized (SingletonDemo3.class) {         sc = instance;         if (sc == null) {           synchronized (SingletonDemo3.class) {             if(sc == null) {               sc = new SingletonDemo3();             }           }           instance = sc;         }       }     }     return instance;   }    private SingletonDemo3() {    } }


静态内部类实现单例

静态内部类特点:线程安全,调用效率高,懒加载

静态内部类单例实现:

1. 定义的类中定义一个静态内部类,静态内部类中定义一个静态常量,创建对象赋值给静态常量

2. 构造方法私有化

3. 定义getInstance()方法返回静态内部类中定义的静态常量

代码:

public class SingletonDemo4 {private static class SingletonClassInstance {           private static final SingletonDemo4 instance = new SingletonDemo4();}private SingletonDemo4(){}//方法没有同步,调用效率高!public static SingletonDemo4  getInstance(){           return SingletonClassInstance.instance;}}

枚举实现单例

枚举实现特点:线程安全,没有懒加载,调用效率高,实现简单,枚举本身就是单例模式,由JVM从根本上提供保障,避免通过反射和反序列化的漏洞

缺点:无延迟加载

枚举实现单例:

  1. 定义枚举类

  2. 在枚举类中定义一个元素

  3. 定义返回枚举中定义的元素

代码:

public enum SingletonDemo5 {     //这个枚举元素,本身就是单例对象!   INSTANCE;     //添加自己需要的操作!   public void singletonOperation(){            System.out.println("枚举实现单例模式");   }}

单例模式总结

主要:

饿汉式(线程安全,调用效率高,不能延时加载)

懒汉式(线程安全,调用效率不高,可以延时加载)

其他

双重检测锁式(由于jvm底层内部模型原型,偶尔会出现问题,不建议使用)

静态内部类(线程安全,调用效率高,可以延时加载)

枚举式(线程安全,调用效率高,不能延时加载,并且可以天然的防止反射和反序列化漏洞)

如何选用?

单例对象 占用资源少,不需要延时加载

枚举好于饿汉式

单例对象 占用资源大,需要延时加载

静态内部类好于懒汉式



0