单例解析

1、普通单例

public class Singleton {    
      //用一个静态变量来记录Singleton类的唯一实例   
      private static Singleton uniqueInstance;   

      private Singleton() {}   

      //注意这个方法也是静态的   
      public static Singleton getInstance() {    
           if(uniqueInstance == null) {   
             uniqueInstance = new Singleton();   
           }   
           return uniqueInstance;   
      }   
}  

问题所在:

  • 线程不安全

2、线程安全的单例1

    //用一个静态变量来记录Singleton类的唯一实例   
    private static Singleton uniqueInstance;   

    private Singleton() {}   

    //注意这个方法也是静态的   
    public static synchronized Singleton getInstance() {    
        if(uniqueInstance == null) {   
             uniqueInstance = new Singleton();   
         }   
         return uniqueInstance;   
    }   

通过增加synchronized关键字到getInstance()方法中,迫使每个线程在进入方法之前,要先等别的线程离开该方法。也就是说,不会有两个线程可以同时进入这个方法。

问题所在:

  • 对1中的单例进行线程安全优化,但同步方法getInstance依然存在实例被创建后重复进入同步方法getInstance,除第一次外,均造成资源浪费
  • 在调用getInstance方法后才正式创建实例

3、线程安全的单例2

public class Singleton {    

    private static Singleton uniqueInstance = new Singleton();

    private Singleton() {}   

    public static Singleton getInstance() {    
         return uniqueInstance;   
    }   
} 

通过调整实例创建的方法在类构造后马上创建实例,提升实例创建速度

问题所在:

  • 在侧重实例返回响应速度的情况下牺牲性能,使用全局静态实例,大大增加消耗

    4、双重校验锁单例

public class Singleton {    

    private volatile static Singleton uniqueInstance;   

    private Singleton() {}   

    public static Singleton getInstance() {    
    if(uniqueInstance == null) { //(1)   
        //只有第一次才彻底执行这里的代码   
       synchronized() {   
          //再检查一次   
          if(uniqueInstance == null)   
            uniqueInstance = new Singleton();   
       }   
    }   
         return uniqueInstance;   
    }   
}

优化点:

  • volatile保证多线程的实例uniqueInstance正确获取
  • synchronized块中代码只在第一次创建实例的时候完整执行,其余线程执行到(1)后等待获取到锁,当进入同步时其它线程已经创建了实例,跳出同步块直接返回实例
  • 既满足了线程安全又满足性能上相对优化
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值