关于线程安全的单例模式

这是我写的第一篇博客请大家多多支持,如果有写的不对的地方,欢迎大家指正批评!

今天和同事做公交车的时候,同事突然问了一下我单例模式,我说这有什么不会写的,但是同事又问了线程安全的单例模式,我也会写但是一问我问什么是安全的,我突然有点蒙,不知道怎么答,故而查了一下资料记录一下

 1 //双重检查锁
 2 public final class DoubleCheckedSingleton  
 3 {  
 4     private static DoubleCheckedSingletonsingObj = null;  
 5   
 6     private DoubleCheckedSingleton(){  
 7     }  
 8   
 9     public static DoubleCheckedSingleton getSingleInstance(){  
10         if(null == singObj ) {
11               Synchronized(DoubleCheckedSingleton.class){
12                      if(null == singObj)
13                            singObj = new DoubleCheckedSingleton();
14               }
15          }
16        return singObj;
17     }  
18 }

至此,上面的写法一方面实现了Lazy-Load,另一个方面也做到了并发度很好的线程安全,一切看上很完美。这是,面试官可能会对你的回答满意的点点头。但是,你此时提出说,其实这种写法还是有问题的!!问题在哪里?假设线程A执行到了第9行,它判断对象为空,于是线程A执行到第12行去初始化这个对象,但初始化是需要耗费时间的,但是这个对象的地址其实已经存在了。此时线程B也执行到了第九行,它判断不为空,于是直接跳到15行得到了这个对象。但是,这个对象还没有被完整的初始化!得到一个没有初始化完全的对象有什么用!!

故而又查了一下静态内部类的实现

public class Singleton {

    private static class LazyHolder {    
       private static final Singleton INSTANCE = new Singleton();    
     }    
     private Singleton (){}    
     public static final Singleton getInstance() {    
        return LazyHolder.INSTANCE;    
     } 

}

单例模式实现方式有好多种,但大部分都会有多线程环境下的问题;使用内部类可以避免这个问题,因为在多线程环境下,jvm对一个类的初始化会做限制,同一时间只会允许一个线程去初始化一个类,这样就从虚拟机层面避免了大部分单例实现的问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值