Java设计模式-单例模式

单例模式:顾名思义,即一个应用程序中只需要存在至多一个对象,比如Delphi和Android中的Application对象,为满足这个要求,我们设计如下代码:

public class Singleton {
    private static Singleton uniqueInstance;

    // other useful instance variables here

    private Singleton() {}

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

    // other useful methods here
}

存在的问题:
但是,上面并不能处理多线程问题,如果现在有两个线程同时在执行getInstance方法,第一个线程刚执行完if (uniqueInstance == null) 还没执行uniqueInstance = new Singleton();这个时候第二个线程也执行到if (uniqueInstance == null),它会发现uniqueInstance还是null,于是进入到了if判断里面。这样你的单例模式就失败了,因为创建了两个不同的实例。

解决办法
加锁:synchronized,代码如下:

public class Singleton {
    private static Singleton uniqueInstance;

    // other useful instance variables here

    private Singleton() {}

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

    // other useful methods here
}

存在的问题:
现在虽然解决了多线程导致有可能产生多个实例的情况,但是每次去执行getInstace方法的时候都会受到同步锁的影响,这样运行的效率会降低

解决办法:
将synchronized关键字从方法声明中去除,把它加入到方法体当中,先检查实例是否已经创建,如果尚未创建才进行同步,这样一来,只有第一次才会同步,代码如下:

public class Singleton {
    private volatile static Singleton uniqueInstance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

注意:volatile关键字确保,当uniqueInstance变量被初始化成Singleton实例时,多个线程正确地处理uniqueInstance变量

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值