单例模式中最常见的双if语句错误
2018-04-04 15:18
232 查看
单例模式中,最常见的代码错误,代码如下:
看起来好像没什么问题.但是由于JVM内部的优化机制.
instance = new Singleton()在JVM中这句话中大概做了以下3件事情
1.给 instance 分配内存
2.调用 Singleton 的构造函数来初始化成员变量
3.将instance对象指向分配的内存空间(执行完这步 instance 就为非 null 了)
在多线程中,JVM的计时编程器中存在指令重排序的优化.也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是1-3-2.如果是后者,当A线程的第3步骤执行完毕,第2步骤还未执行之前.B线程抢到锁时,此时的instance已经是非null了(但是没有初始化),此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了。
这时候我们可以把代码改成
public class Singleton {
//持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载
private volatile static Singleton instance=null;
//私有构造方法
private Singleton(){
}
//静态工程方法,创建实例
public static Singleton getInstance(){
if (instance == null) {
synchronized (instance) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
细心的同学会发现,此时我把 instance 变量声明成 volatile .
当instance声明为instance时,他能保证JVM中3个步骤依次进行..
如果,你觉得这篇文章对你有帮助.你可以点赞鼓励一下我噢.
public class Singleton { //持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 private static Singleton instance=null; //私有构造方法 private Singleton(){ } //静态工程方法,创建实例 public static Singleton getInstance(){ if (instance == null) { synchronized (instance) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
看起来好像没什么问题.但是由于JVM内部的优化机制.
instance = new Singleton()在JVM中这句话中大概做了以下3件事情
1.给 instance 分配内存
2.调用 Singleton 的构造函数来初始化成员变量
3.将instance对象指向分配的内存空间(执行完这步 instance 就为非 null 了)
在多线程中,JVM的计时编程器中存在指令重排序的优化.也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是1-3-2.如果是后者,当A线程的第3步骤执行完毕,第2步骤还未执行之前.B线程抢到锁时,此时的instance已经是非null了(但是没有初始化),此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了。
这时候我们可以把代码改成
public class Singleton {
//持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载
private volatile static Singleton instance=null;
//私有构造方法
private Singleton(){
}
//静态工程方法,创建实例
public static Singleton getInstance(){
if (instance == null) {
synchronized (instance) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
细心的同学会发现,此时我把 instance 变量声明成 volatile .
当instance声明为instance时,他能保证JVM中3个步骤依次进行..
如果,你觉得这篇文章对你有帮助.你可以点赞鼓励一下我噢.
相关文章推荐
- if语句常见的错误
- Py中的条件判断,if语句总结以及常见错误
- 容易令人忽视的if、else语句逻辑错误
- State模式(状态模式)消除烦琐的if..else语句
- 编程时避免使用 if 语句的五种模式
- Oracle 语句常见错误
- KVM使用NAT模式启动,错误:qemu-ifup-nat failed with status 256
- sql语句常见错误
- 编程时避免使用 if 语句的五种模式
- 10种Java开发者编写SQL语句时常见错误
- shell 中 if语句的语法错误
- C语句常见的错误
- SQL语句与常见错误
- 编程时避免使用 if 语句的五种模式
- Java建造者模式以及常见误区错误分析纠正
- shell 中 if语句的语法错误
- Linux下单分支if语句下 unary operator expected错误解决方法
- shell 中 if语句的语法错误
- 判断语句常见错误
- nginx配置if错误语句时出错一例