单例模式的 8 种写法!

📖摘要


今天分享下 —— 单例模式的 8 种写法! 的一些基本知识,欢迎关注!

单例模式即一个 JVM 内存中只存在一个类的对象实例。

在这里插入图片描述


🌂分类


👨懒汉式

类加载的时候就创建实例

示例1

public class Singleton {  

    private static Singleton instance;  

    private Singleton (){}  

    public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  

}

线程不安全,不可用。

示例2

public class Singleton {  

    private static Singleton instance;  

    private Singleton (){}  

    public static synchronized Singleton getInstance() { 
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  

}

同步方法,线程安全,效率低,不推荐。

示例3

public class Singleton {

    private static Singleton singleton;

    private Singleton() {}

    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                singleton = new Singleton();
            }
        }
        return singleton;
    }

}

线程不安全,会产生多个实例,不可用。


👨饿汉式

使用的时候才创建实例
当然还有其他的生成单例的方式,双重校验锁,枚举和静态内部类,文中会有介绍。

无线程安全问题,不能延迟加载,影响系统性能。

示例1

public class Singleton {  

    private static Singleton instance = new Singleton();  

    private Singleton (){}  

    public static Singleton getInstance() {  
        return instance;  
    }  

}

示例2

public class Singleton {  

    private static Singleton instance = null;  

    static {  
        instance = new Singleton();  
    }  

    private Singleton (){}  

    public static Singleton getInstance() {  
        return instance;  
    }  

}

示例3

public class Singleton {

    private static volatile Singleton singleton;

    private Singleton() {}

    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }

        }
        return singleton;
    }

}

双重校验锁,线程安全,推荐使用。

示例4

public class Singleton {  

    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  

    private Singleton (){}  

    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE;  
    }  

}

静态内部类,线程安全,主动调用时才实例化,延迟加载效率高,推荐使用。

示例5

public enum Singleton {  

    INSTANCE;  

    public void whateverMethod() {  

    }  

}

💥注意事项
  1. 考虑多线程问题
  2. 单例类构造方法要设置为private类型禁止外界new创建
private Singleton() {}
  1. 如果类可序列化,考虑反序列化生成多个实例问题,解决方案如下
private Object readResolve() throws ObjectStreamException {

    // instead of the object we're on, return the class variable INSTANCE  

    return INSTANCE;  

}

枚举类型,无线程安全问题,避免反序列化创建新的实例,很少使用。


🚀使用场景

  1. 工具类对象
  2. 系统中只能存在一个实例的类
  3. 创建频繁或又耗时耗资源且又经常用到的对象

另外,Spring 容器中的实例默认是单例饿汉式类型的,即容器启动时就实例化 bean 到容器中,当然也可以设置懒汉式 defalut-lazy-init="true" 为延迟实例化,用到时再实例化。


🎉最后

  • 更多参考精彩博文请看这里:《陈永佳的博客》

  • 喜欢博主的小伙伴可以加个关注、点个赞哦,持续更新嘿嘿!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈永佳

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值