JAVA设计模式-创建型模式(如何创建对象)-单例模式学习

一、饿汉式

 饿汉式比较简单,在程序编译期间完成初始化操作,无线程安全问题,使用可靠。唯一的

缺点是 内存,不管程序是否用得到,先完成实例化。日常开发中推荐使用,
这样像瓜式的编程显然是不够的,不管是面试的需要,还是提高代码的质量,都需要学习懒汉式。

public class Singleton {

private static Singleton instance = new Singleton();

private Singleton() {

}

//获取单例实例
public static Singleton getInstance() {
    return instance;
    }
}

二、懒汉式

懒汉式 名义是在需要的时候实例化对象,这种延后切治带来的好处式加快项目的启动和节约内存。当然延后治化也带来了诸多问题,需要开发者逐一来解决。

 案例1
本实现看似解决了懒汉式延后实例化的问题,但是存在 线程问题 ,即在多线程环境下,存在单例不唯一的情况。

public class Singleton {

private static Singleton instance = null;
private Singleton() {

}

//获取单例实例
public static Singleton getInstance() {
    if(null == instance ){
        instance = new Singleton();
    }
    return instance;
    }
}

 案例2

针对上述存在的线程问题,很容易想到的是使用 synchronized 锁来控制并发,从而回避线程问题。单例不唯一的问题是解决了,然而却带来了并发性能问题.

缺点:

当多线程环境下获取单例实例时,由于 getInstance 方法是加锁的(阻塞锁),并发访问转化为串行访问,性能严重降低。对于一名有追求的技术人怎么能凑合呢,必须继续优化!

public class Singleton {

private static Singleton instance = null;
private Singleton() {

}

//获取单例实例
public synchronized  static Singleton getInstance() {
    if(null == instance ){
        instance = new Singleton();
    }
    return instance;
    }
}

案例3 :  双重检查机制,降低锁的颗粒度,解决并发时的性能问题

当通过 getInstance 方法获取单例实例对象时,如果不为 NULL,则直接返回,如果为 NULL.线程到这里转化为顺序执行。
第一个获取锁的线程通过 new 创建新实例然后释放锁,后续线程检查实例已经不为NULL ,直接返回,无需重复实例。

虽然已经相对完善

缺点:并发场景下会存在异常。

public class Singleton {

private static Singleton instance = null;
private Singleton() {

}

//获取单例实例
public  static Singleton getInstance() {
    if(null == instance ){
        synchronized(Singleton.class){
            if(null == instance ){
                instance = new Singleton();
            }

        }
    }    
 return instance;
 }

    
}

案例4:

上述实现仍然存在一点瑕疵:在并发场景下,仍然会存在某一刻出现 运行异第 的情况。这也是给程序员幻觉的根本原因,代码像抽筋了似的,不知道怎么报错了,也不知道怎么变好了,
问题产生的根源是 Java指今重排,更具体地说是通过 new 关键字创建对象时指令重排,应对方式是通过 volatile 关键字抑制指令重排。

public class Singleton {

private static volatile Singleton instance = null;
private Singleton() {

}

//获取单例实例
public  static Singleton getInstance() {
    if(null == instance ){
        synchronized(Singleton.class){
            if(null == instance ){
                instance = new Singleton();
            }

        }
    }    
 return instance;
 }

    
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值