don*_*ton 38 java singleton multithreading synchronization thread-safety
关于Singletons的维基百科文章提到了一些在Java中实现结构的线程安全方法.对于我的问题,让我们考虑具有冗长初始化过程并且同时被许多线程所占据的单身人士.
首先,这个未提及的方法是否是线程安全的,如果是这样,它会同步什么?
public class Singleton {
private Singleton instance;
private Singleton() {
//lots of initialization code
}
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
Run Code Online (Sandbox Code Playgroud)
其次,为什么以下实现线程在初始化时是安全且懒惰的?如果两个线程同时进入该getInstance()方法会发生什么?
public class Singleton {
private Singleton() {
//lots of initialization code
}
private static class SingletonHolder {
public static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
Run Code Online (Sandbox Code Playgroud)
最后,在第二个示例中,如果一个线程首先获取实例而另一个线程获取实例并尝试在构造函数在第一个线程中完成之前对其执行操作,该怎么办?那你可以进入一个不安全的状态吗?
Boh*_*ian 46
答案1:static synchronized方法使用类对象作为锁 - 即在这种情况下Singleton.class.
答案2:java语言,其中包括:
这两个事实意味着在SingletonHolder调用getInstance()方法之前不会加载内部静态类.此时,在调用的线程被赋予访问权限之前,该类的静态实例将作为类加载的一部分进行实例化.
这一切都意味着我们有安全延迟加载,并没有任何需要同步/锁!
这种模式是用于单身人士的模式.它击败了其他模式,因为它MyClass.getInstance()是单身人士的事实行业标准 - 每个使用它的人都会自动知道他们正在处理单身人士(使用代码,显然总是很好),因此这种模式具有正确的API 和正确的实现引擎盖.
顺便说一句比尔Pugh的文章是值得理解的单身模式时阅读的完整性.