常用设计模式-单例模式(Singleton pattern)

常用设计模式-单例模式(Singleton pattern)

一、单例模式目的

使用单例模式第一步要了解其作用,单例理解为一个实例(one instance)。保证一个类只有一个它的实例。在实际开发中,如线程池,数据库连接对象等。

二、实现思路

为了保证 one class one instance

①则需要保证实例全局唯一,保证实例全局唯一的方式这里选用的是可以使用 static 关键字修饰实例引用,静态字段全局共享,但是需要保证该实例引用自始至终只引用一个实例。实例可以在 bean 创建时创建(饥饿模式),也可以在需要时才实例化(减轻服务器压力,懒惰模式)。

②并且构造函数只能私有化,避免任何线程都能 new 一个实例

③其次开放一个访问入口,即属于类的 get 静态方法,用 static 修饰。

④获取实例时需要先判断实例已经创建才获取,未创建需要创建唯一的实例,下面为双重验证 + volatile方式创建实例的实现

双重验证 + volatile

public Class Singleton(){
    private volatile static Singleton uniqueInstance;

private Singleton() {
}

public static Singleton getUniqueInstance() {
   //先判断对象是否已经实例过,没有实例化过才进入加锁代码
    if (uniqueInstance == null) {
        //类对象加锁
        synchronized (Singleton.class) {
            if (uniqueInstance == null) {
                uniqueInstance = new Singleton();
            }
        }
    }
    return uniqueInstance;
}
}

如果单使用双重验证,由于已获得锁的线程在创建实例时,线程分三步执行指令(分配内存空间地址,初始化实例,引用指向内存空间地址),三步操作并非按排序进行,有可能先执行了第 3 步再执行第 2 步,另一线程在第一次验证时判断到实例引用不为空,即返回,线程对该实例引用的后续使用会造成空指针异常 。因此需要使用 volatile 保证指令不被重排序

但如果单使用 volatile,则不能保证线程实例化时这个操作的原子性。因此双重验证 + volatile便是处于这样的考虑。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值