博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单例模式备忘
阅读量:4647 次
发布时间:2019-06-09

本文共 1663 字,大约阅读时间需要 5 分钟。

  单例模式需要备忘的部分为:如何创建线程安全的懒汉式单例类

  首先java不能使用DCL写法,如下:

1     /**  2      * 实现单例访问Kerrigan的第四次尝试  3      */   4     public class SingletonKerriganD {   5         6         /**  7          * 单例对象实例  8          */   9         private static SingletonKerriganD instance = null;  10        11         public static SingletonKerriganD getInstance() {  12             if (instance == null) {  13                 synchronized (SingletonKerriganD.class) {  14                     if (instance == null) {  15                         instance = new SingletonKerriganD();  16                     }  17                 }  18             }  19             return instance;  20         }  21     }

  假设线程一执行到instance = new SingletonKerriganD()这句,这里看起来是一句话,但实际上它并不是一个原子操作(原子操作的意思就是这条语句要么就被执行完,要么就没有被执行过,不能出现执行了一半这种情形)。事实上高级语言里面非原子操作有很多,我们只要看看这句话被编译后在JVM执行的对应汇编代码就发现,这句话被编译成8条汇编指令,大致做了3件事情:

  1.给Kerrigan的实例分配内存。

  2.初始化Kerrigan的构造器

  3.将instance对象指向分配的内存空间(注意到这步instance就非null了)。

  但是,由于Java编译器允许处理器乱序执行(out-of-order),以及JDK1.5之前JMM(Java Memory Medel)中Cache、寄存器到主内存回写顺序的规定,上面的第二点和第三点的顺序是无法保证的,也就是说,执行顺序可能是1-2-3也可能是1-3-2,如果是后者,并且在3执行完毕、2未执行之前,被切换到线程二上,这时候instance因为已经在线程一内执行过了第三点,instance已经是非空了,所以线程二直接拿走instance,然后使用,然后顺理成章地报错

  那么实现方法为:

1 /**  2  * 实现单例访问Kerrigan的第六次尝试  3  */   4 public class SingletonKerriganF {   5     6     private static class SingletonHolder {   7         /**  8          * 单例对象实例  9          */  10         static final SingletonKerriganF INSTANCE = new SingletonKerriganF();  11     }  12    13     public static SingletonKerriganF getInstance() {  14         return SingletonHolder.INSTANCE;  15     }

 

转载于:https://www.cnblogs.com/dingshuai/p/3262194.html

你可能感兴趣的文章
Java的内存泄漏
查看>>
152-PHP htmlspecialchars函数
查看>>
061-PHP函数定义默认参数
查看>>
Genymotion下载模拟器失败解决方案
查看>>
The Apostrophe and the Quote Function ‘和引用函数 未翻译完)
查看>>
kv.go
查看>>
利用截取字符串,生成已声明的字符串中的4位随机验证码。
查看>>
Spring 事务模型
查看>>
【MM系列】SAP S/4 HANA BP创建客户/供应商的一点想法
查看>>
【HANA系列】SAP HANA XS使用JavaScript数据交互详解
查看>>
【HANA系列】SAP HANA SQL获取上周的周一
查看>>
对称矩阵
查看>>
轮播图笔记!
查看>>
值类型与引用类型
查看>>
This kernel requires an x86-64 CPU, but only detected an i686 CPU.
查看>>
PAT 1023 Have Fun with Numbers[大数乘法][一般]
查看>>
三维空间中的几种坐标系
查看>>
乘法表
查看>>
4.express 框架
查看>>
Java基础算法集50题
查看>>