标签:场景 对象 instance 实例 单例 memory 列举 序列化
1反射对单例模式的破坏
采用反射的方式另辟蹊径实例了该类,导致程序中会存在不止一个实例。
解决方案
其思想就是采用一个全局变量,来标记是否已经实例化过了,如果已经实例化过了,第 二次实例化的时候,抛出异常
2clone()对单例模式的破坏
当需要实现单例的类允许clone()时,如果处理不当,也会导致程序中出现不止一个实例
解决方案
重写clone()方法,调clone()时直接返回已经实例的对象
3序列化对单例模式的破坏
在使用序列化/反序列化时,也会出现产生新实例对象的情况
解决方案
在反序列化时的回调方法 readResolve()中返回单例对象
4指令重排导致懒汉式单例模式失效
看似简单的一段赋值语句:instance = new Singleton();,其实JVM内部已经转换为多条指令:
memory = allocate(); //1:分配对象的内存空间
ctorInstance(memory); //2:初始化对象
instance = memory; //3:设置instance指向刚分配的内存地址
但是经过重排序后如下:
memory = allocate(); //1:分配对象的内存空间
instance = memory; //3:设置instance指向刚分配的内存地址,此时对象还没被初始化
ctorInstance(memory); //2:初始化对象
可以看到指令重排之后,instance指向分配好的内存放在了前面,而这段内存的初始化被排在了后面,在线程A初始化完成这段内存之前,线程B虽然进不去同步代码块,但是在同步代码块之前的判断就会发现instance不为空,此时线程B获得instance对象进行使用就可能发生错误
解决方案
private static volatile Singleton instance = null;
仅作为个人学习总结使用 如有侵权请联系删除
标签:场景,对象,instance,实例,单例,memory,列举,序列化 来源: https://blog.csdn.net/u010219345/article/details/114964400
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。