以下两个代码在多线程环境方面有何不同?
代码1:
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
代码2:
class Singleton {
private static Singleton uniqueInstance;
private Singleton() { ... }
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
为什么Code 2在多线程环境中不起作用,当它还声明了静态变量时,一旦加载了类就会加载它因此它只有一个实例?
谢谢!
答案 0 :(得分:4)
请记住,多个线程可以在给定时间调用getInstance
。
在示例1中,uniqueInstance
成员的初始化程序保证只运行一次 - 在类加载时。
在示例2中,由于初始化在getInstance
内联进行,因此多个线程可以独立并同时找到uniqueInstance
成员变量为null
。然后每个线程将调用new Singleton()
,其结果取决于两个(或更多)线程的时间。
要使示例2起作用,您可以(例如)在synchronized
方法上添加getInstance
。
关于在类加载时初始化完全变量的注释对于示例1是正确的,但对于2没有 - 在示例2中,成员变量在类加载时设置为null
在第一次调用getInstance
期间,时间,但后来填充了一个对象实例。
答案 1 :(得分:1)
多个线程可能位于:
内if (uniqueInstance == null) {
...
}
同时处理。