單例模式是一種應(yīng)用非常廣泛的設(shè)計(jì)模式,用于保證一個類在程序生命周期內(nèi)只能創(chuàng)建一次,并提供全局唯一的訪問這個類的方法,也就是getInstance方法。單例有兩種常用的寫法:懶漢式和餓漢式。
懶漢式舉例:
public class SingletonLan {
// 3 定義靜態(tài)變量來存儲創(chuàng)建好的類實(shí)例
private static SingletonLan instance = null;
// 1 私有化構(gòu)造函數(shù)
private SingletonLan(){
}
// 2 定義靜態(tài)方法提供類的實(shí)例
public static SingletonLan getInstance(){
// 4 判斷存儲類實(shí)例的變量是否存在
if(instance == null){
// 4.1 不存在就創(chuàng)建
instance = new SingletonLan();
}
// 4.2 存在的話就直接返回
return instance;
}
}
餓漢式舉例:
public class SingletonE {
// 1 私有化構(gòu)造函數(shù)
private SingletonE(){
}
// 3 定義一個靜態(tài)變量保存類的實(shí)例
private static SingletonE instance = new SingletonE();
// 2 定義一個靜態(tài)類來提供類實(shí)例
public static SingletonE getInstance(){
// 4 返回創(chuàng)建好的實(shí)例
return instance;
}
}
懶漢式與餓漢式的區(qū)別:
- 懶漢式是延遲加載的,當(dāng)使用到單例時才開始實(shí)例化,而餓漢式是程序開啟就實(shí)例化完成了。
- 懶漢式不是線程安全的,而餓漢式線程安全。
單例模式一般在緩存的時候使用,當(dāng)某些外部資源頻繁的被使用時,可以先將這些資源讀到內(nèi)存中,下次訪問的時候就可以直接從內(nèi)存中讀取了,這樣就可以節(jié)省大量的時間。在Android開發(fā)中解析配置文件的Manager、Sharepreference的管理器一般都是使用單例。緩存是一種典型的空間換時間的方案。
實(shí)際項(xiàng)目應(yīng)用:TreeAccessoryStateManager
public class TreeAccessoryStateManager {
public static final int ACCE_STATUS_NOT_BUY = 0;
public static final int ACCE_STATUS_BOUGHT_NOT_USE = 1;
public static final int ACCE_STATUS_BOUGHT_USE = 2;
// 此處使用餓漢式單例,主要是為了確保線程安全
private static final TreeAccessoryStateManager instance = new TreeAccessoryStateManager();
public static TreeAccessoryStateManager getInstance() {
return instance;
}
private Map<Integer, GoodsItem> accessoryMap;
private TreeAccessoryStateManager() {
//由于這個map在主線程和render thread都有頻繁改動,改成ConcurrentHashMap,暫時避免大部分問題。
accessoryMap = new ConcurrentHashMap<Integer, GoodsItem>();
}
public int getAcceStatus(int acceId) {
GoodsItem goodsItem = accessoryMap.get(acceId);
if (goodsItem != null) {
return goodsItem.getStatus();
}
return ACCE_STATUS_NOT_BUY;
}
}