[英]About Singleton pattern in java, instead of assigning static variable to new local variable in method, why not use directly static variable?
我还没有理解代码的用途=> DataProvider instance = sInstance; 在下面的方法。 有人帮我解释一下吗? 为什么不直接使用sInstance?
private static volatile DataProvider sInstance = null;
public static DataProvider getInstance() {
DataProvider instance = sInstance;
if (instance == null) {
synchronized (DataProvider.class) {
instance = sInstance;
if (instance == null) {
instance = sInstance = new DataProvider();
}
}
}
return instance;
}
它用作延迟初始化(ei仅在需要时创建单例实例)。 这段代码的问题在于它已被破坏。 显然即使使用同步块,也有可能出现问题(由于竞争条件)。 因此,如果您想要安全,请不要使用此方法!
替代方案:使用直接分配(就像你想要的那样);
private static volatile DataProvider sInstance = new DataProvider();
或使用枚举(由@MadProgrammer建议);
public enum DataProvider
{
INSTANCE;
// singleton content
}
根据约书亚布洛赫的书Prentice.Hall.Effective.Java.2nd.Edition.May.2008,
特别是,对局部变量结果的需求可能不清楚。 这个变量的作用是确保该字段在已经初始化的常见情况下只读一次。 虽然不是绝对必要,但这可以提高性能,并且通过应用于低级并发编程的标准更加优雅。 在我的机器上,上面的方法比没有局部变量的明显版本快25%。
主要原因是挥发性。 正如@Hien Nguyen的回答,它提高了25%的性能。 原因易失性总是从主内存而不是缓存中获取数据,所以它太慢了。 声明instance = sInstance以避免多次从主存储器读取数据(慢)。 如果我们不使用临时变量,我们有3次从sInstance读取数据,所以我们使用temp变量会提高性能。
请参阅此主题以了解访问Volatile缓慢的原因: 为什么访问volatile变量比成员慢约100?
您的答案可能与此主题相同: Java:在双重检查习语中使用局部变量
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.