单例模式

单例模式目的:

为了确保一个类在内存中只有一个对象,该对象须自动创建并且对外提供。

优缺点

优点:在内存中只有一个对象,可以节省系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统性能。
缺点:责任过重,没有抽象层,很难扩展

如何实现类在内存中只有一个对象呢?

a:构造私有,不然直接new就可以创建
b:在成员位置手动创建一个对象
c:对外提供公共访问方法,为了保证外界能直接使用该方法,用static修饰

两种实现方式:
饿汉式

类一加载就创建对象(不会出问题,开发用,Runtime类运用)

public class Singleton{
        private Singleton(){}//构造方法私有,防止new对象
        private static Singleton singleton=new Singleton();//静态并私有保证只创建一次且不被外界修改
        public static Singleton getSingleton(){
                return singleton;
        }
}
懒汉式

用到的时候才去创建对象(懒加载:面试用),可能会出现线程安全问题(加同步)

public class Singleton {
        private Singleton(){};//构造私有
        private static volatile Singleton singleton=null;
        public synchronized static Singleton getSingleton(){
                if(singleton==null){
//不是原子性操作,需要加volatile保证内存可见性
                        return singleton=new Singleton();
                }
                return singleton;
        }
}
双重锁校验

根据阿里巴巴开发手册,通过双重检查锁(double-checked locking)(在并发场景)实现延迟初始化的优化问题隐患:
双重检验锁:效率高;( 解决问题:问题1:假如两个线程A、B,A执行了if (instance == null)语句,它会认为单例对象没有创建,此时线程切到B也执行了同样的语句,B也认为单例对象没有创建,然后两个线程依次执行同步代码块,并分别创建了一个单例对象。 )

public class Singleton {
    private static volatile Singleton instance = null;//volatile的一个语义是禁止指令重排序优化 private Singleton(){}
    public static Singleton getInstance() {
//提高效率,不等于null时不用获取锁
        if (instance == null) {
//多线程可以进入这中间,所以加第二个if
            synchronized (Singleton.class) {
                if (instance == null) {//2保证返回instance一定在创建对象后,因为instance=new Singleton()不是原子性语句,所以加入
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

问题二:可能返回null
instance = new Singleton();分为三步
1)在堆上开辟空间;(2)属性初始化;(3)引用指向对象
//三个内容为三条单独指令,因指令重排可能会导致执行顺序为1->3->2(正常为1->2->3),当单例模式中存在普通变量需要在构造方法中进行初始化操作时,单线程情况下,顺序重排没有影响;但在多线程情况下,假如线程1执行singleton=new Singleton()语句时先1再3,由于系统调度线程2的原因没来得及执行步骤2,但此时已有引用指向对象也就是singleton!=null,故线程2在第一次检查时不满足条件直接返回singleton,此时singleton为null(即str值为null)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值