设计模式 单例模式

单例模式的定义

单例模式是指确保一个类在任何情况下都只有一个实例,并且提供一个访问该单例的全局访问点。

如何创建一个单例模式

构造函数需要是 private 访问权限的,这样才能避免外部通过 new 创建实例;

考虑对象创建时的线程安全问题;

考虑是否支持延迟加载;

考虑 getInstance() 的性能(是否加锁)

单例模式适用的场景

J2EE 标准中的 ServletContext 和 ServletContextConfig;

Spring 框架应用中的 ApplicationContext、数据库中的连接池等也都是单例模式。

饿汉式(饥渴型)单例模式

在类加载的时候就创建对象,不会出现线程安全问题(因为还没有开始加载的时候就创建好了对象,线程都没有机会去争夺)。

复制代码
package SingletonFactoryModel;

public class SingletonHungry {
    //成员变量 在类加载的时候就把对象创建好了
    static SingletonHungry s = new SingletonHungry();
    // 1.构造方法私有化
    private SingletonHungry(){}
    // 返回就是私有类已经创建好的对象
    private static SingletonHungry getInstance(){
        return s;
    }

    public static void main(String[] args) {
        SingletonHungry instance = SingletonHungry.getInstance();
        SingletonHungry instance1 = SingletonHungry.getInstance();
        System.out.println(instance1 == instance);

    }
}
懒汉式(懒狗)单例模式

懒汉式:在需要的时候才创建,类加载时不创建对象, 直接创建对象可能会有线程安全问题,导致重复创建不同对象,通过施加 双重校验锁来实现对同一对象的获取

java 复制代码
package SingletonFactoryModel;

public class SingletonLazy {
    // 通过 volatile  关键字保证 数据的原子性
    /*
        一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
        保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
        禁止进行指令重排序。
     */
    private  volatile static SingletonLazy singletonLazy;

    private SingletonLazy(){}

    public static SingletonLazy getInstance() {
        // 检查是否需要创建
        if (singletonLazy == null) {
            // synchronized 保证同一时刻只有一个对象去调用
            synchronized (SingletonLazy.class){
                // 因为前面施加了同步块 可能会导致 两个线程都校验为空重复创建对象,需要再次判断为空
                if(singletonLazy == null){
                    singletonLazy = new SingletonLazy();
                }
            }
        }
        return singletonLazy;
    }

    public static void main(String[] args) {
        SingletonLazy instance = SingletonLazy.getInstance();
        SingletonLazy instance1 = SingletonLazy.getInstance();
        System.out.println(instance == instance1);
    }
}
相关推荐
猿究院_夏燊3 小时前
Spring Bean 生命周期
java·后端·spring
Wang's Blog4 小时前
Java 项目实战: 交友项目:登录链路回顾与今日任务地图
java·开发语言·状态模式·交友
信誓旦旦的程序猿4 小时前
【Python量化实战宝典 #08】可转债与债券接口手册:转股价·溢价率·纯债价值(Python 可跑)
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
砚底藏山河4 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
Jlzn88884 小时前
华东电芯分选通道数怎么配才不堵线
java·人工智能·架构·自动化·制造
香吧香5 小时前
GRPC连接机制---长连接分析
java·网络与传输协议
我是人✓5 小时前
SpringBoot项目的五种创建方式
java·spring boot·后端
Wang's Blog5 小时前
Java 项目实战: 交友项目 - 阿里云 OSS 入门案例:从创建 Bucket 到上传拿到可访问 URL
java·阿里云·交友
裕晟资质规划6 小时前
三类涉密资质延续时限差异分析:军工60日与集成印制3个月的边界
java·服务器·前端·网络·安全
念念清晰6 小时前
000-OpenJDK17 源码构建:MacOS环境(M芯片)
java·后端