双重检测单例类

单例类有很多种,有饿汉式,懒汉式。其中懒汉式由于其两次判断被称为双重检测单例类。

看一段代码。

 

 1 public class StoreKeeper {
 2     /** 属性列表值. */
 3     private HashMap<String, Store> storepool = null;
 4     private HashMap<String, Long> lifepool = null;
 5     private static StoreKeeper instance;
 6     private StoreKeeper(){
 7         storepool = new HashMap<String, Store>();
 8         lifepool = new HashMap<String, Long>();
 9     }
10     public static StoreKeeper getInstance(){
11         if (instance == null) {
12             synchronized (StoreKeeper.class) {
13                 if (instance == null) {
14                     instance = new StoreKeeper();
15                 }
16             }
17         }
18         return instance;
19     }
View Code

双重检测单例类即不会每次调用都要获取锁,又做到了延迟加载所以大家都喜欢使用到这种方式,但是双重检测模式在java里面有些问题,主要是JVM会对代码执行重排序等其他的优化策略,所以导致可能返回的实例对象中的成员变量还没有初始化,导致其他线程引用这个对象时得到的成员变量数据不一致,因为获取到的这个实例中的成员变量还未初始化为用户指定的值

 

解决方法:

    

在实例变量增加关键字volatile

private static volatile StoreKeeper instance;

这样就不会出现问题了,因为jvm看到有这个volatile关键字就不会对这段代码

进行重排序优化,所以双重检测机制都要求加上这个volatile关键字.

转载于:https://www.cnblogs.com/yaoyuan23/p/5586801.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值