我看到有一个针对Singleton的在线教程,以实现多线程并确保实例只实例化一次。本教程下面有代码,但在代码中,有重复代码,因为他们想确保实例不为null。
if(instance == null){}
但是,这个条件检查出现两次,这是重复吗?
public class Singleton {
private static Singleton instance;
private Singleton(){
//Here runs a lot code, that's why we don't want to instantiate here
}
// Using synchronized to ensure Singleton (only instantiate once) when
//implement multi threading.
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
它没有重复。它再次被检查,因为在第一次检查if(instance == null)
和锁定synchronized(Singleton.class)
之间,另一个线程可以实例化它并打破单例。检查第一个代码块和第二个代码块之间的差异。
public static Singleton getInstance(){
if(instance == null){
// Another thread could instantiate in this moment.
synchronized(Singleton.class){
instance = new Singleton(); // If another thread did already instantiate it, this would be the second call to the constructor.
}
}
return instance;
}
锁定完成后再次检查可防止该竞争状况。
public static Singleton getInstance(){
if(instance == null){
// Another thread could instantiate in this moment.
synchronized(Singleton.class){
// Now this code is thread safe
if(instance == null){
// No other thread made a race condition before the first check and the locking. We can safely do the heavy work.
instance = new Singleton();
}
}
}
return instance;
}