设计模式之单例模式(饿汉式,懒汉式)

本文深入探讨了饿汉式和懒汉式两种单例模式的实现方式,并重点解析了懒汉式单例模式中双重检查锁定的原理及其在并发场景下的应用。

饿汉式单例模式

public class Singleton1{
    /**一开始就创建了一个实例**/
    private static Singleton1 instance = new Singleton1();
    /**提供静态的公共方法,获得唯一实例**/
    public static Singleton1 getInstance(){
        return instance;
    }
    /**私有的构造方法**/
    private Singleton1(){
    }
}

懒汉式单例模式(已优化)

public class Singleton2{
    private static Singleton2 instance = null;
    /**提供静态的公共方法,获得唯一实例**/
    public static Singleton2 getInstance(){
        /**判空**/
        if(instance==null){
            /**若为空,上锁,其他线程在外面等待**/
            synchronized(Singleton2.class){  
            /**再判一次空,以防等后面的线程进来之后直接创建一个新的实例**/
                if(instance==null){
            /**若为空,则new一个实例**/
                    instance = new Singleton2();
                }
            }
        return instance;
        }
    }
    /**私有构造方法**/
    private Singleton2(){
    }
}
以上的懒汉式,为什么要进行两次判空呢?懒汉式单例模式涉及并发的问题。

第一个判空,是判断当前的实例是否为空,若不为空的话,则进入准备创建一个新的实例,所以这时候必须用synchronized上锁,防止其他线程也判断为空进来创建实例,换言之它在准备要创建实例的时候不允许其他线程进来。接下来再判断一次空,是因为上锁之后可能其他线程在synchronized外面排队,等第一个实例创建完之后,其他线程进来了,如果这时候不判断实例是否为空就创建,就可能又创建一个实例,违背了单例模式了。

为什么synchronized放在第一个判空里面而不是放在方法声明?

请看一下代码:

/**提供静态的公共方法,获得唯一实例**/
/**由于使用synchronized会影响性能,若放在方法声明里,则会每次调用getInstance()获取实例的时候都上锁,导致性能降低**/
public static synchronized Singleton2 getInstance(){

}

若使用两次判空,把synchronized放到方法里面,通过第一个判空可减少了synchronized的执行次数。

/**提供静态的公共方法,获得唯一实例**/
    public static Singleton2 getInstance(){
        /**判空**/
        if(instance==null){
            /**若为空,上锁,其他线程在外面等待**/
            synchronized(Singleton2.class){  
            /**再判一次空,以防等后面的线程进来之后直接创建一个新的实例**/
                if(instance==null){
            /**若为空,则new一个实例**/
                    instance = new Singleton2();
                }
            }
        return instance;
        }
    }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值