【演算法】單例模式Singleton
阿新 • • 發佈:2021-07-20
單例模式Singleton
1.含義
單例模式:即一個類只能建立一個例項。
- 只有一個例項 --> 不可以從類外new物件 --> 構造器私有化private --> 從類裡建立例項;
- 這個物件供外部使用 --> 該例項的get方法 --> 沒有物件,隨著類載入 --> 方法宣告為static --> 靜態只能調靜態 --> 該例項也宣告為static;
2.實現
2.1 餓漢式
public class Singleton(){ //1.私有化構造器; private Singleton(); //2.建立例項;靜態; private static Singleton singleton = new Singleton(); //3.獲取例項的公共方法;靜態; public static Singleton getSinggleton(){ return singleton; } }
特點
多執行緒安全:是;
lazy初始化:否;
類載入就建立例項,浪費記憶體;
2.2 懶漢式,執行緒不安全
public class Singgleton(){ private Singleton(); private static Singleton singleton; //延遲建立物件; public static Singleton getSingleton(){ if(singleton == null){ //呼叫方法的時候沒有了再建立; singleton = new Singleton(); } return singleton; } }
特點
多執行緒安全:否 (當有多個執行緒操作時,可能會有多個執行緒都經過if判斷語句,就會建立多個例項,造成執行緒不安全);
lazy初始化:是;
2.3 懶漢式,執行緒安全
public class Singleton(){ private Singleton(); private static Singleton singleton; //給方法加鎖; public static synchronized Singleton getSingleton(){ if(singleton == null){ singleton = new Singleton(); } return singleton; } }
特點
多執行緒安全:是
lazy初始化:是
效率:低(每次都只是一個執行緒拿到鎖,呼叫方法,多個執行緒無法同時呼叫方法)
2.4 雙重檢驗鎖
public class Singleton(){
private Singleton();
//使用volatile宣告:
//1.禁止指令重排;
//2.保證變數修改後對所有執行緒可見,指示JVM,這個變數是共享且不穩定的,每次用要到主存中去讀取;
private volatile static Singleton singleton();
public static Singleton getSingleton(){
if(singleton == null){ //判斷有沒有例項化過,沒有再進入加鎖模式,這樣絕大多數的都不會再進入了;
synchronized(Singleton.class){
if(singleton == null){ //再判斷一次,因為可能有多個執行緒都經過了前面的if,if不判斷就會建立多個物件了;
singleton == new Singleton();
}
}
}
return singleton;
}
}
多執行緒安全:是
lazy初始化:是
效率:高
- 第一個檢驗是為了效率;
- 第二個檢驗為了執行緒安全;
直接加鎖再判斷 --> 效率低;
先判斷再加鎖 --> 效率高;