单例创建方法与双重检查锁定

单例创建方法与双重检查锁定

Singleton类定义如下:

public class Singleton {
    public static Singleton instance;
    private Singleton() { ; }  // 注意此处定义为私有构造方法
    /**
     * 获取单例 
     */
    public static Singleton getInstance() { ... }
}

单例创建的一般方法

public static Singleton getInstance() {
    if (instance == null) {
        instance = new Singleton();
    }
    return instance;
}

显然一般方法对于单线程模式下的单例创建是有效且无误的。然而对于多线程情形,由于线程间竞争关系的存在,当线程1进入if语句块而并未成功创建instance实例时,此时若线程2进入if语句块,那么也将会创建新的实例,这并不是我们想要的单例模式。

单例创建的同步方法

public synchronized static Singleton getInstance() {
    if (instance == null) {
        instance = new Singleton();
    }
    return instance;
}

利用synchronized方法,可以防止某线程在创建单例时,其他线程进入getInstance类方法去创建单例。然而这种方法存在性能上的缺陷,因为每次调用getInstance方法,都将付出线程同步的代价。

单例创建的双重锁定方法

public static Singleton getInstance() {
    if (instance == null) {
        synchronized(Singleton.class) {
            if (instance == null) {
                // 在Singleton构造函数执行之前,instance变量可能变为非null的
                instance = new Singleton();
            }
        }
    }
    return instance;
}

双重锁定方法可以解决性能缺陷问题,理论上只有一个线程会进入synchronized块,其他线程不会进入。然而Java内存模型并不保证每次都能达到理论效果,也许会存在无序写入的问题。
instance = new Singleton();的伪码解释如下:

mem = allocate();           // allocate memory for Singleton object
instance = mem;             // note that now instance is non-null, but has not been initialized
createSingleton(instance);  // invoke constructor for Singleton passing instance

单例创建的饿汉式方法

static {
    instance = new Singleton();
}

public static Singleton getInstance() {
    return instance;
}

这种方法在类被加载时就创建实例对象,性能友好而内存不友好。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值