四種單例模式實際都是有運用的。
優點:延遲加載
缺點:不加同步的懶漢式是線程不安全的,加了synchronized之後就變成線程安全的了
public class Singleton {
private static Singleton singleton = null;
private Singleton(){
}
public static synchronized Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
優點:線程安全
缺點:浪費內存空間
實例應用:java.lang.Runtime
public class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return singleton ;
}
}
特點:性能又保證線程安全
注意:其實雙重檢查模式就是對懶漢模式的優化,在new Singleton之前,加一個類鎖。注意,成員變量singleton最好使用volatile修飾,否則若在無參構造中初始化一個其他的成員變量,會產生指令重排序,導致新創建的對象獲取不到最新的成員變量值。
public class Singleton{
private static volatile Singleton singleton;
private Singleton(){
}
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
特點:既實現懶加載,性能好,線程安全
聲明類時,成員變量中不聲明實例變量,而是放到靜態內部類中。這種方式和懶漢式有些相似,它們都採用了類裝載的機制來保證初始化實例時只有一個線程,不同的是,Holder單例模式是將實例的初始化放到了靜態類中去實現,從而實現了懶加載。
因爲private static HolderSingleton instance = new HolderSingleton();只會被加載一次
public class HolderSingleton {
// 外部類的私有構造方法
private HolderSingleton() {
}
// 外部類靜態方法,通過靜態內部類的靜態成員變量獲取
public static HolderSingleton getInstance() {
return Holder.instance;
}
// 靜態內部類內部加載的時候創建外部類,只加載一次,所以只創建一個
private static class Holder {
private static HolderSingleton instance = new HolderSingleton();
}
}