逸笔记-设计模式-单例模式

2023-02-14  本文已影响0人  lovefy

1.什么是单例模式

单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例),就好比有一口井,只需要一个桶就可以打水上来了,不需要额外的桶来进行打水操作。这就是单例模式

2.单例模式有哪些设计方式

单例模式,主流的设计方式有两种,一种是懒汉,另一种是饿汉。其中懒汉模式,顾名思义,就是比较懒在代码初始化的时候就生成一个唯一实例给你,就像我们去井李打水,懒汉模式就是比较懒,井建好的时候,需要打水的时候采取买一个桶去打水。饿汉模式,就如其名,很饿了,狠不得立马去吃饭那种,就像井建好了以后,立马买一个桶,不管有没有打水的需求。所以我们根据这些特点,来写代码

1.懒汉模式

package cn.com.lovefy.demo;

/**
* @author lyf
*/
public class LazyOneDemo {
    private static volatile LazyOneDemo lazyOneDemo;
    //不允许对象被实例化
    private LazyOneDemo(){
    }
    /**
* 获取实例
* @return {@link LazyOneDemo}
*/
    public static LazyOneDemo getInstance() {
        if(lazyOneDemo!=null){
            synchronized (LazyOneDemo.class){
                if(lazyOneDemo!=null) {
                    lazyOneDemo = new LazyOneDemo();
                }
            }
        }
        return lazyOneDemo;
    }

}

特点:延时加载,只有在正在需要的时候才开始实例化。
1、线程安全问题
2、双重判断double check,加锁优化(锁也可以直接加锁到方法上,但是会耗费性能)
3、使用volatile关键字,防止指令重排序

2.饿汉模式

package cn.com.lovefy.demo;

/**
* @author lyf
*/
public class HunglyOneDemo {
    private static  HunglyOneDemo hunglyOneDemo = new HunglyOneDemo();
    //不允许对象被实例化
    private HunglyOneDemo(){
    }
    /**
* 获取实例
* @return {@link HunglyOneDemo}
*/
    public static HunglyOneDemo getInstance() {
        return hunglyOneDemo;
    }

}

特点:类加载的初始化阶段就完成了实例的初始化,本质上是借助于jvm的类加载机制,保证实例的唯一性。(急加载)
类加载机制:
1、加载:加载二进制文件到内存中,并生成对应的class数据结构
2、连接:包括验证、准备(给静态变量赋默认值,引用类型为null,int为0,boolean为false等等)、解析(将符号应用替换为直接引用)
3、初始化(执行静态代码块、给静态变量赋初值)
注意:如果当前类的父类没有被加载,则会先加载父类

3.其他单例的实现

1.内部静态类的实现

class InnerOneDemo {
    private static class InnerOneDemoHolder {
        private static InnerOneDemo innerOneDemo= new InnerOneDemo();
    }
    //不允许被实例化
    private InnerOneDemo(){
    }
    /**
    * 获取实例
    * @return {@link InnerOneDemo}
    */
    public static InnerOneDemo getInstance() {
        return InnerOneDemoHolder.innerOneDemo;
    }
}

特点:也是借助jvm的类加载机制,保证实例的唯一性(懒加载)
当访问instance时才会初始化实例
缺点:可以通过反射进行破坏
2.枚举的形式实现

package com.demo.Enum;

/**
* @BelongsProject: demo
* @BelongsPackage: com.demo.Enum
* @Author: liyifan
* @CreateTime: 2023-02-13 09:56
* @Description: 枚举单例模式
*/
public enum OneEnum {
    ONE;

    public static OneEnum getInstance(){
        return ONE;
    }
}

特点:简单,线程安全,也能够防护反射攻击(禁止反射实例化enum类型类)。

上一篇 下一篇

猜你喜欢

热点阅读