19、设计模式之单例模式-懒汉式

/**
 * 懒汉式-单例模式
 * 多线程模式慎用,单例模式会失效,为解决这一问题,可以在静态方法上加“synchronized”表明锁住该类本身,同一时间点只有一个线程可以访问该方法
 * 该方法虽然可以解决单例失效的问题,但却非常的消耗资源
 */
public class LazySingleton {
    private static LazySingleton instance = null;

    private LazySingleton(){

    }

    private synchronized static LazySingleton getInstance(){
        if(instance==null){
            instance = new LazySingleton();
        }
        return instance;
    }

    /**
     * 与上述方法等效
     * @return
     */
    private static LazySingleton getNewInstance(){
        synchronized(LazySingleton.class) {
            if (instance == null) {
                instance = new LazySingleton();
            }
        }
        return instance;
    }
}

进一步完善,解决资源占用过多的问题

/**
 * 引入双重锁概念,完善懒汉式-单例模式
 */
public class LazyDoubleCheckSingleton {

    private volatile static LazyDoubleCheckSingleton instance = null;

    private LazyDoubleCheckSingleton(){

    }

    public static LazyDoubleCheckSingleton getInstance(){
        if(instance==null){
            synchronized (LazyDoubleCheckSingleton.class) {
                if(instance==null) {
                    instance = new LazyDoubleCheckSingleton();
                    // 这种方式虽然极大地解决了资源占用多过的问题,但也是存在线程安全性问题
                    // new 一个对象实际执行了三步操作,如下
                    // 1、为对象分配内存地址
                    // 2、初始化对象
                    // 3、将instance指向 新分配的内存地址
                    // 正常情况下,执行顺序1->2->3 如此执行,但多线程会造成重排序现象1->3->2,如要禁止该现象发生,
                    // 只需要在instance变量声明上加入一个关键字“volatile”,
                    // 多线程下 系统会有共享内存,volatile会使所有线程都能看见该变量的最新状态,
                    // 在赋值的时候,会将当前行缓存数据写回到共享内存,这样其他线程缓存的数据就会失效,从而再次向共享内存获取该变量的最新数据
                }
            }
        }
        return instance;
    }
}

第二种完善方式,静态内部类

/**
 * 完善懒汉式-单例模式 第二种方式:静态内部类
 * 由于静态内部类被调用时,系统会先获取类对象锁,这样一来,多线程之间就屏蔽了StaticInnerClassSingleton 类实例化的全过程,
 * 重排序现象仅对当前线程可见且有效
 */
public class StaticInnerClassSingleton {

    private StaticInnerClassSingleton(){

    }
    private static class InnerClass{
        private static StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
    }

    public static StaticInnerClassSingleton getInstance(){
        return InnerClass.instance;
    }
}

【切记】单例模式,一定要记得创建私有构造函数

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值