这是一个例子:
http://www.tutorialspoint.com/java/java_using_singleton.htm
在查看第一个示例时,当用户写入:Singleton.getInstance()
时,它会调出:
new Singleton()
我没有得到它,它是如何单独的,每当它创建一个新的单例对象?
我理解第二个例子。如果singleton
为null,则创建新对象,但在第一个示例中,它始终创建新对象??
那是什么?
答案 0 :(得分:10)
不,在第一个示例中,new Singleton()
的唯一电话就在这里(Singleton
内):
private static Singleton singleton = new Singleton( );
这是一个静态变量初始值设定项。它将被执行一次,并且仅在需要时执行。 (如果您从未触及Singleton
类,则不会执行初始化程序。)
答案 1 :(得分:1)
在第二个例子中,正如有人提到的那样,它不是线程安全的。以下是使getInstance()方法线程安全的两个选项:
public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
public static Singleton getInstance() {
if (singleton == null) {
synchronized(Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
该方法的第二个版本允许您获取已构造的单例实例,而不会产生任何同步开销。但是,如果为null,则输入synchronized块。如果有线程上下文切换并且第二个线程实际进入同步块之前,则再次检查null。这确保只构建一个实例。
任何一种方法都应该完全是线程安全的。
答案 2 :(得分:0)
只有在加载类时才会调用new Singleton()
。
答案 3 :(得分:0)
成员singleton
被声明为静态,因此new Singleton()
只被调用一次。
答案 4 :(得分:0)
该行:
private static Singleton singleton = new Singleton( );
只在加载类时执行一次 - 它是一个类字段初始值设定项。
请看这个问题:Best Practice: Initialize class fields in constructor or at declaration? - 这个问题与new Random()
的想法相同。
编辑:我突然进入Stack Overflow看看我是否可以回答一个未回答的问题,在我提交回复之前,看起来其他三个人已经回复了它。我喜欢Stack Overflow!