華為云云容器快速搭建網站實踐隨記—利用公有映象搭建WordPress
阿新 • • 發佈:2020-10-22
date: 2020-09-28 16:09:00
updated: 2020-09-28 17:42:00
單例模式
1. 餓漢式
public class EHan {
private static EHan instance = new EHan();
private EHan(){}
public static EHan getInstance(){
return instance;
}
}
優點:沒有執行緒安全問題
缺點:在初始化時就建立好了,浪費記憶體空間
2. 懶漢式
2.1 執行緒不安全
public class LHan { private static LHan instance; private LHan(){} public static LHan getInstance(){ if(instance == null){ instance = new LHan(); } return instance; } }
優點:只有當用的時候才檢查是否有例項,沒有才建立
缺點:有執行緒安全與不安全兩種,區別在於是否有 synchronized 關鍵字
2.2 執行緒安全
public class LHan { private static LHan instance; private LHan(){} public static synchronized LHan getInstance(){ if(instance == null){ instance = new LHan(); } return instance; } }
3. DCL
由於執行緒安全的懶漢式的 synchronized 是加在方法上的,如果該方法裡還有其他的一些程式碼,會降低執行效率,加鎖的粒度太粗,所以可以進而改寫下面這個
3.1 懶漢式優化後的一種寫法
public class LHan { private static LHan instance; private LHan(){} public static LHan getInstance(){ if(instance == null){ synchronized(this){ instance = new LHan(); } } return instance; } }
但是這種寫法也存在一定問題,當執行緒A在判斷instancenull後停住了,此時還沒有建立例項;執行緒B搶到了資源,發現instancenull,也會進入到程式碼塊,於是A和B都會建立一個例項。
3.2 DCL 單例模式
Double Check Lock 兩次檢查,中間插入一個lock
public class LHan {
private static volatile LHan instance; // 必須要加 volatile
private LHan(){}
public static LHan getInstance(){
if(instance == null){ // 這一層判斷是為了提高效率。鎖競爭很耗費時間和效率,避免多個執行緒每一次getInstance都要進入到同步程式碼塊
synchronized(this){
if(instance == null){
instance = new LHan();
}
}
}
return instance;
}
}
有可能會存在,A在第一層判斷結束後停住,B進入同步程式碼塊,new一個物件例項,進行一定操作後,把instance置為null,然後A進入同步程式碼塊,會再次new一個物件。解決:新增版本號。
4. 靜態內部類
public class Singleton {
private static class SingletionHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton(){}
public static final Singleton getInstance(){
return SingletionHolder.INSTANCE;
}
}
靜態內部類的方式效果類似雙檢鎖,但實現更簡單。但這種方式只適用於靜態域的情況,雙檢鎖方式可在例項域需要延遲初始化時使用。