双重检测单例类
2016-06-15 11:18
309 查看
单例类有很多种,有饿汉式,懒汉式。其中懒汉式由于其两次判断被称为双重检测单例类。
看一段代码。
View Code
双重检测单例类即不会每次调用都要获取锁,又做到了延迟加载所以大家都喜欢使用到这种方式,但是双重检测模式在java里面有些问题,主要是JVM会对代码执行重排序等其他的优化策略,所以导致可能返回的实例对象中的成员变量还没有初始化,导致其他线程引用这个对象时得到的成员变量数据不一致,因为获取到的这个实例中的成员变量还未初始化为用户指定的值
解决方法:
在实例变量增加关键字volatile
private static volatileStoreKeeper instance;
这样就不会出现问题了,因为jvm看到有这个volatile关键字就不会对这段代码
进行重排序优化,所以双重检测机制都要求加上这个volatile关键字.
看一段代码。
public class StoreKeeper { /** 属性列表值. */ private HashMap<String, Store> storepool = null; private HashMap<String, Long> lifepool = null; private static StoreKeeper instance; private StoreKeeper(){ storepool = new HashMap<String, Store>(); lifepool = new HashMap<String, Long>(); } public static StoreKeeper getInstance(){ if (instance == null) { synchronized (StoreKeeper.class) { if (instance == null) { instance = new StoreKeeper(); } } } return instance; }
View Code
双重检测单例类即不会每次调用都要获取锁,又做到了延迟加载所以大家都喜欢使用到这种方式,但是双重检测模式在java里面有些问题,主要是JVM会对代码执行重排序等其他的优化策略,所以导致可能返回的实例对象中的成员变量还没有初始化,导致其他线程引用这个对象时得到的成员变量数据不一致,因为获取到的这个实例中的成员变量还未初始化为用户指定的值
解决方法:
在实例变量增加关键字volatile
private static volatileStoreKeeper instance;
这样就不会出现问题了,因为jvm看到有这个volatile关键字就不会对这段代码
进行重排序优化,所以双重检测机制都要求加上这个volatile关键字.
相关文章推荐
- JS/JQ常见兼容辅助插件
- web聊天相关知识
- 报表生成笔记
- spark组件之graphx函数方法(二)
- java 中类的加载顺序
- 关于在eclipse中使用ctypes 如何处理编码的问题
- 问题:在文件里设的ip和ifconfig查出来的不一致
- oracle10g升级补丁后无法启动实例
- 十三、linux curl详解
- sql server2008 获取动态sql的变量值
- eclipse 下调整jdk和tomcat的jvm参数
- centos6.x中yum安装nginx
- 《道德经》的三个重要版本
- 创建数据库
- Python利用MonkeyRunner操作手机
- 通过jsp和servlet实现后台界面完成对数据库的增删改查
- House Robber II
- 如何判断一个实例或者一个类实现某接口呢?
- http和HTTPS形象介绍
- C++中虚析构函数的作用