本文的思想来源于:
[b]Jeremy Manson[/b] and [b]Brian Goetz[/b], 《[b]JSR 133 (Java Memory Model) FAQ[/b]》, February 2004, http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#synchronization
"double-checked locking"经常被用于Singleton模型中实现lazy load,典型的"double-checked locking"代码如下所示:
然后由于reordering的存在,instance 的初始化有可能会被move到getInstance之后执行。这种情况下,
虽然在getInstance()方法中,instance被正确的赋值,但是之后又被初始化为null。下面的程序打印的结果为null。
由于volatile的特性(参加另一篇文章《volatile关键词的原理与用途》),这个问题显然可以通过将instance字段声明为volatile来fix。但是更为简单直观的方法为:
[b]Jeremy Manson[/b] and [b]Brian Goetz[/b], 《[b]JSR 133 (Java Memory Model) FAQ[/b]》, February 2004, http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#synchronization
"double-checked locking"经常被用于Singleton模型中实现lazy load,典型的"double-checked locking"代码如下所示:
// double-checked-locking - don't do this!
// initialization
private static Something instance = null;
public static Something getInstance() {
if (instance == null) {
synchronized (this) {
if (instance == null)
instance = new Something();
}
}
return instance;
}
然后由于reordering的存在,instance 的初始化有可能会被move到getInstance之后执行。这种情况下,
虽然在getInstance()方法中,instance被正确的赋值,但是之后又被初始化为null。下面的程序打印的结果为null。
public static Something getInstance() {
if (instance == null) {
synchronized (this) {
if (instance == null)
instance = new Something();
}
}
return instance;
}
private static Something instance = null;
public static void main(String[] args) {
Something instance = getInstance();
System.out.println(instance);
}
由于volatile的特性(参加另一篇文章《volatile关键词的原理与用途》),这个问题显然可以通过将instance字段声明为volatile来fix。但是更为简单直观的方法为:
public Class LazySomething{
// static inner class
private static class LazySomethingHolder {
public static Something something = new Something();
}
public static Something getInstance() {
return LazySomethingHolder.something;
}
}