【发布时间】:2013-02-25 22:40:42
【问题描述】:
class MyClass
{
private static volatile Resource resource;
public static Resource getInstance()
{
if(resource == null)
resource = new Resource();
return resource;
}
}
如果您使用易失性,安全发布发生(即,一旦引用对另一个线程可见,数据也可用),我的怀疑是在实践中根据 java 并发性。那么我可以在这里使用它吗?但如果它是正确的,那么假设 thread1 现在检查“资源”并且它为空,因此它开始创建对象。当 thread1 创建对象时,另一个线程即 thread2 来并开始检查“resource”的值,thread2 发现它为 null(假设创建“resource”对象需要相当长的时间,并且由于 thread1 尚未完成创建,所以安全发布没有发生,因此 thread2 不可用)那么它也会开始创建对象吗?如果是,则类不变量中断。我对么?请在这里帮助我理解 volatile 的这种特殊用法。
【问题讨论】:
-
你不会在单例中使用
volatile。 根据定义,单例中的私有实例不会改变,这意味着线程不存在缓存旧值的危险。这忽略了您当前具有非线程安全实现,因为您的getInstance未同步。使用enum在 Java 中创建单例。 -
对于几乎所有用途,您不妨只使用初始化表达式,因为类加载是延迟完成的。如果您出于其他原因使用该类,可能没有使用此实例(听起来很糟糕),那么包含静态的嵌套类将很好地完成这项工作。
-
如果您绝对必须使用单例,请考虑:en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom
标签: java concurrency