您好,登錄后才能下訂單哦!
在日常開發(fā)過程中時常需要用到設(shè)計模式,但是設(shè)計模式有23種,如何將這些設(shè)計模式了然于胸并且能在實際開發(fā)過程中應(yīng)用得得心應(yīng)手呢?和我一起跟著《Android源碼設(shè)計模式解析與實戰(zhàn)》一書邊學(xué)邊應(yīng)用吧!
今天我們要講的是單例模式
定義
確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例
使用場景
確保某個類有且只有一個對象的場景,避免產(chǎn)生多個對象消耗過多的資源
某個類型的對象只應(yīng)該有一個
使用例子
實現(xiàn)
實現(xiàn)的要點
常見的實現(xiàn)方式
餓漢單例模式
public class Singleton { private static final Singleton singleton = new Singleton(); //構(gòu)造函數(shù)私有化 private Singleton() { } //公有的靜態(tài)函數(shù),對外暴露獲取單例對象的接口 public static Singleton getInstance() { return singleton; } }
餓漢單例模式采用的是靜態(tài)變量 + fianl關(guān)鍵字的方式來確保單例模式,應(yīng)用啟動的時候就生成單例對象,效率不高
懶漢模式
public class Singleton { private static Singleton singleton; //構(gòu)造函數(shù)私有化 private Singleton() { } //公有的靜態(tài)函數(shù),對外暴露獲取單例對象的接口 public static synchronized Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } }
懶漢模式的主要問題在于由于加了synchronized關(guān)鍵字,每調(diào)用一次getInstance方法,都會進(jìn)行同步,造成了不必要的開銷
以上的2種模式用的都不多,了解一下就好,下面介紹平時用得比較多的單例模式
Double Check Lock(DCL)模式(雙重檢查鎖定模式)
public class Singleton { private static Singleton singleton = null; //構(gòu)造函數(shù)私有化 private Singleton() { } //公有的靜態(tài)函數(shù),對外暴露獲取單例對象的接口 public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
DCL模式是使用最多的單例模式,它不僅能保證線程安全,資源利用率高,第一次執(zhí)行g(shù)etInstance時單例對象才會實例化;同時,后續(xù)調(diào)用getInstance方法時又不會有懶漢模式的重復(fù)同步的問題,效率更高;在絕大多數(shù)情況下都能保證單例對象的唯一性
DCL模式的缺點是第一次加載時由于需要同步反應(yīng)會稍慢;在低于JDK1.5的版本里由于Java內(nèi)存模型的原因有可能會失效
靜態(tài)內(nèi)部類單例模式
public class Singleton { private Singleton() { } public static Singleton getInstance() { return SingletonHolder.sInstance; } //靜態(tài)內(nèi)部類 private static class SingletonHolder { private static final Singleton sInstance = new Singleton(); } }
第一次加載Singleton類時不會初始化sInstance,只有在第一次調(diào)用getInstance方法時才會初始化sInstance,延遲了單例對象的實例化
靜態(tài)內(nèi)部類單例模式不僅能保證線程安全也能保證單例對象的唯一性
靜態(tài)內(nèi)部類單例模式和DCL模式是推薦的單例實現(xiàn)模式
枚舉單例
public enum Singleton { INSTANCE; }
默認(rèn)枚舉實例的創(chuàng)建是線程安全的,并且在任何情況下它都是一個單例
其他的單例模式,在一種情況下會出現(xiàn)失效的情況——反序列化,但是枚舉即使在反序列化情況下也不會失效
總結(jié)
單例模式是運用頻率很高的模式,由于在客戶端一般沒有高并發(fā)的情況,現(xiàn)在的JDK版本也已經(jīng)到了9了,一般推薦用DCL模式和靜態(tài)內(nèi)部類2種實現(xiàn)。
單例對象的生命周期很長,如果持有Context,很容易引發(fā)內(nèi)存泄漏,所以傳遞給單例對象的Context最好是Application Context
最后加點福利
單例模式的代碼格式都是固定的,每次都要那么寫有點麻煩,咱們可以用添加模板的方法來偷懶,詳情見圖。
添加了模板后,在需要實現(xiàn)單例模式的類里面直接輸入你的模板名字,如圖中的sin, Android Studio就會出現(xiàn)提示,回車搞定!趕緊試試吧!
源碼地址:https://github.com/snowdream1314/ImageLoader
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。