我想在Java中实现多线程的延迟初始化。
我有一些类似的代码:
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
Helper h;
synchronized(this) {
h = helper;
if (h == null)
synchronized (this) {
h = new Helper();
} // release inner synchronization lock
helper = h;
}
}
return helper;
}
// other functions and members...
}
我得到了“双重检查锁定被打破”的声明。
我该如何解决这个问题呢?
发布于 2010-08-27 03:21:47
以下是正确的双重检查锁定的模式。
class Foo {
private volatile HeavyWeight lazy;
HeavyWeight getLazy() {
HeavyWeight tmp = lazy; /* Minimize slow accesses to `volatile` member. */
if (tmp == null) {
synchronized (this) {
tmp = lazy;
if (tmp == null)
lazy = tmp = createHeavyWeightObject();
}
}
return tmp;
}
}
对于单例,有一个更具可读性的习惯用法,用于惰性初始化。
class Singleton {
private static class Ref {
static final Singleton instance = new Singleton();
}
public static Singleton get() {
return Ref.instance;
}
}
发布于 2010-08-27 03:27:12
在Java中正确执行双重检查锁定的唯一方法是在相关变量上使用"volatile“声明。虽然该解决方案是正确的,但请注意,“易失性”意味着每次访问时都会刷新缓存线。因为"synchronized“会在块的末尾刷新它们,所以它实际上可能不会更有效(甚至更低)。我建议不要使用双重检查锁定,除非您已经对代码进行了概要分析,并且发现这方面存在性能问题。
发布于 2010-08-27 03:15:38
定义应使用volatile
修饰符进行双重检查的变量
您不需要h
变量。下面是来自here的一个示例
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
}
https://stackoverflow.com/questions/3578604
复制相似问题