版本一:
// Single threaded version
class Foo {
private static Helper helper = null;
private Helper(){
}
public static Helper getHelper() {
if (helper == null)
helper = new Helper();
return helper;
}
// other functions and members...
}
版本二:
// Correct but possibly expensive multithreaded version
class Foo {
private Helper helper = null;
public synchronized Helper getHelper() {
if (helper == null)
helper = new Helper();
return helper;
}
// other functions and members...
}
版本三(DCL):
// Broken multithreaded version
// "Double-Checked Locking" idiom
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
helper = new Helper();
}
}
}
return helper;
}
// other functions and members...
}
DCL还是会失效,最重要的2个原因如下:
1, 编译器优化了程序指令, 以加快cpu处理速度.
2, 多核cpu动态调整指令顺序, 以加快并行运算能力.
解决一:
// Works with acquire/release semantics for volatile
// Broken under Java 1.4 and earlier semantics for volatile
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
// other functions and members...
}
解决二:
public class Foo {
// 似有静态内部类, 只有当有引用时, 该类才会被装载
private static class LazyFoo {
public static Foo foo = new Foo();
}
public static Foo getInstance() {
return LazyFoo.foo;
}
}
参考:
http://kenwublog.com/explain-java-memory-model-in-detail(涉及了很多Java底层的东西,值得一看)
http://en.wikipedia.org/wiki/Double-checked_locking