阅读 180

玩转设计模式(单例模式)(设计模式实战)

序言

单例模式在实际工作中的应用场景非常多,概念非常简单,就是整个程序中,有且只允许有一个实例。例如:我们程序中存放一个当前用户信息的类,我们使用单例模式,可以确保在任何页面获取信息时拿的都是同一个对象,这样可以保持状态的一致性。

单例模式的类型

也许会有疑惑,单例模式为啥还会有类型,这是因为实例的创造时机导致。

  1. 懒汉式:只有在需要使用时,才去创建实例

  2. 饿汉式:在类加载时就先创建好,等待被使用

懒汉式创建单例对象

懒汉式创建对象的方法是在程序使用对象前,先判断该对象是否已经实例化(判空),若已实例化直接返回该类对象。否则则先执行实例化操作。

public class Singleton {
    
    private static Singleton singleton;
    
    private Singleton(){}
    
    public static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
    
}复制代码

以上方式其实还会存在一个隐形问题,就是如果两个线程同时判断singleton为null,那么他们都会去实例化一个对象,这样就成了多例。所以,我们要解决的是线程安全问题。

我们常用的方法,就是加个锁

public static synchronized Singleton getInstance() {
    if (singleton == null) {
        singleton = new Singleton();
    }
    return singleton;
}
// 或者
public static Singleton getInstance() {
    synchronized(Singleton.class) {   
        if (singleton == null) {
            singleton = new Singleton();
        }
    }
    return singleton;
}复制代码

这样就规避了两个线程同时创建Singleton对象的风险。

但是引来另外一个问题:每次去获取对象都需要先获取锁,并发性能非常地差,极端情况下,可能会出现卡顿现象。 所以我们提出优化设想:目标是如果没有实例化对象则加锁创建,如果已经实例化了,则不需要加锁,直接获取实例

public static Singleton getInstance() {
    if (singleton == null) {  // 线程A和线程B同时看到singleton = null,如果不为null,则直接返回singleton
        synchronized(Singleton.class) { // 线程A或线程B获得该锁进行初始化
            if (singleton == null) { // 其中一个线程进入该分支,另外一个线程则不会进入该分支
                singleton = new Singleton();
            }
        }
    }
    return singleton;
}复制代码

饿汉式创建单例对象

饿汉式在加载时已经创建好该对象,在程序调用时直接返回该单例对象即可,即我们在编码时就要马上创建这个对象,不需要等到被调用时再去创建。

public class Singleton{
    
    private static final Singleton singleton = new Singleton();
    
    private Singleton(){}
    
    public static Singleton getInstance() {
        return singleton;
    }
}复制代码

注意上面的代码在第3行已经实例化好了一个Singleton对象在内存中,不会有多个Singleton对象实例存在

类在加载时会在堆内存中创建一个Singleton对象,当类被卸载时,Singleton对象也随之消亡了。


作者:coolFish
链接:https://juejin.cn/post/7036009322492461064

 伪原创工具 SEO网站优化  https://www.237it.com/ 


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐