【23种设计模式】单例模式

一、单例模式是什么

单例模式指的是一种常用的软件设计模式,类创建单一实例以满足多方调用,即一个类只有一个对象实例

二、单例模式优缺点

优点
单例模式只构建单一实例,供多个方法使用,避免多个方法构造同个类多个对象,减少内存的开销。
缺点
单例模式没有接口,也没有抽象层,扩展性性差,如需扩展,需在原有代码上进行修改。

三、单例模式实现形式

1.懒汉模式

懒汉模式也就是“懒”,当需要时再创建实例,如下:

public class Singleton {
    private Singleton() {}
    private static Singleton single=null;
    public static Singleton getInstance() {
         if (single == null) {  
             single = new Singleton();
         }  
        return single;
    }
}

可见简单的不加锁的懒汉模式是线程不安全的
例如:A、B线程同时访问时,此时刚进来两者的single都为null,A线程还没到new Singleton(),此时B线程到了if (single == null)语句,判断到single为null,那么也new Singleton(),就导致生成两个实例

那么就来说说如何让他线程安全
1.加方法锁synchronized

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; 
    }

但是这样每次进来都会加锁,其实我们也就是再第一次进来实例后就不需要再实例了。那么可以再加一层判断不为空,即不是第一次进来,已创建实例,就不需要进行加锁创建实例。如下:

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

由于Java指令重排问题,优化实例中加入锁volatile

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;
    }
    
}

稍微讲讲重排列
线程A,B同时访问,此时还未创建实例, A线程获取到锁,此时JVM为singleton分配内存,还未初始化,B线程进行判断singleton时,不为空,即返回,导致有空指针出现。volatile可以保证可见性,从而避免这种问题出现。

2.饿汉模式

饿汉模式即“饿”,它先创建实例,“饿”的时候,也就是方法调用它的时候,它就直接返回自身已经创建的实例返回。

public class Singleton {
    private Singleton() {}
    private static final Singleton single = new Singleton(); 
    public static Singleton getInstance() {
        return single;
    }
}   

3.两种模式类型对比

“懒汉”就是很“懒”,等调用再创建实例。“饿汉”是“饿”,它不懒,它先创建好实例,需要的时候直接返回。看了饿汉模式是否会觉得饿汉模式代码简洁,还线程安全,用起来非常方便。但是也会有它的缺点,懒汉模式也是有他的优点的。两种类型优缺点如下:
①.懒汉模式
优点: 减少内存的开销,需要时再创建
缺点: 需注意线程安全问题

②.饿汉模式
优点: 线程安全
缺点: 不用时自动创建好实例,占用内存

这样一看,如果是很注重内存分配的项目,则采用懒汉模式会更好,如果更注重代码简洁,不是很注重内存的项目,可采用饿汉模式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值