.NET Core AWS S3雲端儲存
技術標籤:Android
1.前言
單例模式應該是用得最多的設計模式之一,如果你的應用有個類很消耗資源 那麼我們沒有理由讓他們不斷建立
2. 定義
確保一個類只有一個例項,而且自行例項化,並向系統提供這個例項。
3.適合場景
確保一個類只有一個物件的地方,避免產生多個物件消耗過多的資源,或者說建立一個物件需要耗費大量的資源 也需要用單例模式。
4.實現的關鍵點
4.1構造方法不對外開發 一般是private
4.2通過一個靜態方法或者列舉返回單例物件
4.3確保單例物件有且只有一個,尤其在多執行緒的環境下
5.多種單例的寫法和優缺點
5.1 餓漢方式
public class Singleton1 { private static final Singleton1 mSingleton1 = new Singleton1(); private Singleton1() { } public static Singleton1 getSingleton1(){ return mSingleton1; } }
優點:實現簡單
缺點:餓漢在初始化宣告的時候就已經初始化了這個物件,會造成記憶體的浪費,可能使用者並不需要這個類,或者用不到
5.2 懶漢方式
public class Singleton2 { private static Singleton2 mSingleton2 = null; private Singleton2() { } public static synchronized Singleton2 getSingleton2() { if (mSingleton2 == null) { mSingleton2 = new Singleton2(); } return mSingleton2; } }
優點:在需要用的時候才初始化,減少資源浪費
缺點:缺點是在用的時候初始化會導致生成比較慢,在多執行緒的情況下會出現執行緒安全的問題,所以需要加鎖,但是在加鎖後又會有每次加鎖的問題,進一步降低了效能。
5.3 DLC
public class Singleton3 { private static volatile Singleton3 mSingleton3 = null; private Singleton3() { } public static synchronized Singleton3 getSingleton3() { if (mSingleton3 == null) { synchronized (Singleton3.class) { if (mSingleton3 == null) { mSingleton3 = new Singleton3(); } } } return mSingleton3; } }
優點:既能夠在第一次用的時候初始化,又能夠執行緒安全,而且能初始化後就不加鎖了
缺點:比較複雜一點
注意 記得加上volatile 關鍵子,因為建立物件不是一個原子操作,可能會導致DCL失效,就是建立了但是沒有初始化, volatile雖然會影響效能,但是跟準確性相比還是值得的
為什麼會失效,就是new 一個物件的時候
1.先分配記憶體
2.初始化成員變數
3.將物件指向分配的空間
由於執行是亂序的,可能先執行了3 再執行2 這樣在多執行緒的情況下會出現沒有初始化的成員變數的情況出現
5.4 靜態內部類
public class Singleton4 {
private static class Singleton4Holder {
private static Singleton4 mSingleton4 = new Singleton4();
}
private Singleton4() {
}
public static synchronized Singleton4 getSingleton4() {
return Singleton4Holder.mSingleton4;
}
}
優點:既能保證執行緒安全,又能保證兼顧效能,推薦使
5.4.1 靜態內部類加鎖原理:
首先要了解類載入過程中的最後一個階段:即類的初始化,類的初始化階本質就是執行類構造器的方法。
方法:這不是由程式設計師寫的程式,而是根據程式碼由javac編譯器生成的。它是由類裡面所有的類變數的賦值動作和靜態程式碼塊組成的。JVM內部會保證一個類的方法在多執行緒環境下被正確的加鎖同步,也就是說如果多個執行緒同時去進行“類的初始化”,那麼只有一個執行緒會去執行類的方法,其他的執行緒都要阻塞等待,直到這個執行緒執行完方法。然後執行完方法後,其他執行緒喚醒,但是不會再進入()方法。也就是說同一個載入器下,一個型別只會初始化一次。
那麼回到這個程式碼中,這裡的靜態變數的賦值操作進行編譯之後實際上就是一個程式碼,當我們執行getInstance方法的時候,會導致Singleton4Holder類的載入,類載入的最後會執行類的初始化,但是即使在多執行緒情況下,這個類的初始化的程式碼也只會被執行一次,所以他只會有一個例項。
5.5 列舉單例
public enum Singleton5 {
INSTANCE;
public void doSomething(){
}
}
優點:既能保證執行緒安全,又能保證兼顧效能,推薦使用
為什麼能保證執行緒的安全?
因為java在編譯器變成class程式碼的時候列舉是一個靜態變數類的載入過程中在初始化的時候會保證靜態變數的執行緒安全載入。
6.單例模式的優缺點
優點
1因為記憶體中只有建立一個例項,能減少記憶體的開銷。
2.因為只有一個物件能減少對資源的佔用,避免死鎖等事情的發生。
缺點:
1.單例模式容易引起記憶體洩露,因為他的生命週期比較長,注意傳遞最好傳遞Application Contenxt
2.單例模式沒有介面,如果有邏輯修改或者擴充套件,那麼只能改到程式碼,不符合高擴充套件性