现在大家都知道“双重检查成例”在java是有问题的,现在不考虑这个问题,或者就当“双重检查成例”在java是没有问题的,但我现在又发现另一个问题,令我十分疑惑,这就是线程安全的问题,且看下面的经典代码:
public class LazySingleton {
private static LazySingleton m_instance;
private LazySingleton() {
} public static LazySingleton getInstance() {
if (m_instance == null) {
synchronized(LazySingleton.class) {
if (m_instance == null) {
m_instance = new LazySingleton();
}
}
}
return m_instance;
}
} 如果有线程A在执行if (m_instance == null) {,而线程B在执行m_instance = new LazySingleton();,结果会怎样?
A在执行if (m_instance == null) {并不是在synchronized里的,这样是线程安全的吗?
public class LazySingleton {
private static LazySingleton m_instance;
private LazySingleton() {
} public static LazySingleton getInstance() {
if (m_instance == null) {
synchronized(LazySingleton.class) {
if (m_instance == null) {
m_instance = new LazySingleton();
}
}
}
return m_instance;
}
} 如果有线程A在执行if (m_instance == null) {,而线程B在执行m_instance = new LazySingleton();,结果会怎样?
A在执行if (m_instance == null) {并不是在synchronized里的,这样是线程安全的吗?
1.null 那就进入同步序列,等待B线程完成初始化,A然后取现成的
2.非null 那直接取现成的关于Out-of-order writes现象,就是
m_instance = new LazySingleton();
m_instance已经非空,但对象还没完成实例化,即new LazySingleton()未完成
详见:
http://www.ibm.com/developerworks/java/library/j-dcl.html
public Date date = null;
}thread A:
run () {
while (true) {
Date date1 = Globe.date;
}
}thread B:
run() {
while (ture) {
Globe.date = new Date();
}
}date1总能得到一个正常的、而非意外的对象吗?我想知道的就是java在对象的赋值和访问是否原子化的?谢谢
public static Date date = null;
}
其实就是个int类型的地址。
多线程的存取应该是原子的
也就是是说,你获取的引用总是一个有效的引用。
否则不是发生内存紊乱了么
写存在原子性问题,java对象赋值在某些情况下不是原子的,就是所谓的Out-of-order writes现象
Date date1 = Globe.date;
这里取