【设计模式】 单例模式好好总结一下

自己理解

单例模式顾名思义,就是在任何时候单例模式的类的有且只能有一个实例,就是单例模式。

自己理解优点

  • 减少内存占用
  • 提高系统性能
  • 实际应用,比如整个系统只需要创建一个实例的情况,或者创建某个实例消耗资源过大... 都可以根据自己的实际应用来制定是否需要用单例模式。

自己思考

知道概念,接下来就是如何创造这个类,这个类和其他类有什么不同。

  • 构造方法私有化。因为这个类有且只能有一个实例,所以要保证构造方法不能对外开放。
  • 访问对象的方法指向唯一的实例。
  • 如何构造这个实例,是在类加载的时候?还是在第一个获取实例对象的时候?

创建方式

1、饿汉式

就是在类加载的过程中创建对象。

实例作为静态变量创建

  • 这种构建方式能通过反射的方式来破坏单例模式内部结构。
java 复制代码
public class Demo {

    /**
     * 构造方法私有化
     */
    private Demo() {
    }

    /**
     * 构造实例 - 类加载过程中
     */
    private static Demo demo = new Demo();

    /**
     * 获取实例方法
     * @return
     */
    public static Demo getDemo(){
        return demo;
    }

    public void mess(){
        System.out.println("hello");
    }
}

实例在静态代码块创建

  • 这种构建方式能通过反射的方式来破坏单例模式内部结构。
java 复制代码
public class Demo {

    /**
     * 构造方法私有化
     */
    private Demo() {
    }

    /**
     * 实例变量
     */
    private static Demo demo;

    /**
     * 类加载过程中 创建实例对象
     */
    static {
        demo = new Demo();
    }

    /**
     * 获取实例方法
     * @return
     */
    public static Demo getDemo(){
        return demo;
    }

    public void mess(){
        System.out.println("hello");
    }
}

枚举的方式创建 (*推荐)

  • 枚举的方式可以避免反射来破坏内部结构。
java 复制代码
public enum Demo {

    DEMO;

    public void mess(){
        System.out.println("hello");
    }
}

2、懒汉式

就是在使用实例的时候才创建这个实例。

创建方式 - 线程不安全

java 复制代码
public class Demo {

    private static Demo demo;

    /**
     * 私有构造方法
     */
    private Demo(){}

    /**
     * 线程不安全
     * 在第一次使用实例对象的时候创建实例
     * @return
     */
    public static Demo getDemo(){
        if(demo == null){
            demo = new Demo();
        }
        return demo;
    }

    public void mess(){
        System.out.println("hello");
    }
}

创建方式 - 线程安全 (* 推荐)

java 复制代码
public class Demo {

    private static Demo demo;

    /**
     * 私有构造方法
     */
    private Demo(){}

    /**
     * 重量级锁 synchronized
     * 在第一次使用实例对象的时候创建实例
     * @return
     */
    public static synchronized Demo getDemo(){
        if(demo == null){
            demo = new Demo();
        }
        return demo;
    }

    public void mess(){
        System.out.println("hello");
    }
}

比较两种创建方式

我主张的一般都是根据实际业务需要、服务器内存使用情况和系统开销来确定使用哪种方式,但是一般情况下,我觉得在业务量不大的情况下,无脑饿汉式足够使用了,更为推荐的是饿汉式中的枚举创建,简单、有效、成熟、而且代码量少。

相关推荐
唐青枫5 分钟前
Java Undertow 实战指南:从轻量 Web Server 到 Spring Boot 嵌入式容器
java
测试界的世清8 小时前
各大厂软件测试面试题+答案纯干货
面试·职场和发展
liang_jy10 小时前
内存管理(七)—— 内存映射
面试·操作系统
前端工作日常10 小时前
我学习到的Java中domain和dto区别
java·后端
liang_jy10 小时前
内存管理(六)—— 进程的内存映像
面试·操作系统
码农学院11 小时前
基于Spring Boot的跨境电商多语言订单管理系统架构设计
java·大数据·spring boot
技术小结-李爽11 小时前
【工具】pom文件的<packaging>
java·maven
l1564694812 小时前
突围!图文混合知识库难以解析,Kimi-K3 原生视觉架构深耕知识工作,DMXAPI 统一接口,缩短项目开发周期
java·大数据·开发语言
布吉岛的石头13 小时前
Java 程序员第 45 阶段11:网关统一路由大模型接口,配合 Nacos 配置治理,灰度路由:基于Nacos元数据实现大模型服务灰度发布与权重路由
java·服务发现
我命由我1234513 小时前
Android 开发问题:Cannot resolve method ‘repeat‘ in ‘String‘
android·java·java-ee·android studio·android jetpack·android-studio·android runtime