单例模式

总所周知,单例模式有两种比较常见的写法,一种是饿汉式,一种是懒汉式。
懒汉式如下:

class Single1{
    private static volatile Single1 instance;
    public static Single1 getInstance(){
        if (instance==null){
            instance = new Single1();
        }
        return instance;
    }
    private Single1(){}
}

就是只有等你调用getInstance的时候,我才会new对象,(只有你需要的时候我才做这件事,所以很懒,叫懒汉式)。
饿汉式如下:

class Single2{
    private static Single2 instance=new Single2();
    private Single2(){}
    public static Single2 getInstance(){
        return instance;
    }
}

也就是一早就new 对象,(早早就准备好,所以也交饿汉式)。
这两个好像是挺容易的,但是懒汉式牵扯到多线程的时候就容易出问题,如果我两个线程同时调用getInstance的时候,可能就会创建两个对象了。
我们实际试验一下:两个线程都是getInstance
结果就出问题了,返回了两个不一样的对象。(心里骂至于一个对象的空间都省吗?)
所以这个时候就要引用锁了,

class Single1{
    private static  Single1 instance;
    public static Single1 getInstance(){
        synchronized (Single1.class) {
            if (instance==null){
            instance = new Single1();
            }
        }
        return instance;
    }
    private Single1(){}
}

锁一下就不会出现问题吧,但是每一次getInstance都要所一下,然后判空等等,这样是不是显得有点烦?
所以就可以先检查一遍,然后在空的话在锁上,锁上之后判断是不是空的,是空的就创建对象。这就叫 双检查锁机制

    private static  Single1 instance;
    public static Single1 getInstance(){
        if (instance==null){
            synchronized (Single1.class){
                if (instance==null) {
                    instance = new Single1();
                }
            }
        }
        return instance;
    }
    private Single1(){}
}

但是众所周知,反射是无所不能的,反射
然后你就会非常开心的发现,如果是反射的时候,每一次都会创建一个新的对象,而这个对象和getInstance拿到的对象也是不一样的。
有人就会问,难道没有安全的单例模式了吗?
有,
就是用枚举做:

enum Single3{
    INSTANCE;
    private Single3(){}
    public static Single3 getInstance(){
        return INSTANCE;
    }
}

用反射测试枚举做的单例
结果会报错,因为emun可以防止反序列化重新创建对象。
另外还有一种写法是静态内部类
代码如下:

class Single4{
    private static class MySingleton{
        private static final Single4 INSTANCE=new Single4();
    }
    private Single4(){}
    public static final Single4 getInstance(){
        return MySingleton.INSTANCE;
    }
}

这个模式的优势在于,getInstance方法并没有被同步,并且只是执行一个域的访问,因此延迟初始化并没有增加任何访问成本。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值