既然來了簡書,總要留下點(diǎn)什么.......
讀書養(yǎng)才氣微峰,勤奮養(yǎng)運(yùn)氣沙兰,寬厚養(yǎng)大氣氓奈,淡泊養(yǎng)志氣
1-What
保證一個(gè)類在任何情況下在程序中都絕對只有一個(gè)實(shí)例,并且提供一個(gè)全局訪問點(diǎn)鼎天。
2-Premise
1.構(gòu)造函數(shù)私有舀奶,防止被外部new對象;
2.內(nèi)部必須提供一個(gè)靜態(tài)的方法斋射,讓外部調(diào)用育勺。
3-Advantage
減少內(nèi)存開銷;
避免資源多重占用罗岖。
4-Disadvantage
不易擴(kuò)展涧至。
5-Classify
5-1-餓漢式
類加載過程中,就已經(jīng)創(chuàng)建了實(shí)例桑包。
public class SingletonE {
//靜態(tài)修飾的實(shí)例南蓬,類在加載時(shí)就是執(zhí)行實(shí)例化操作
private static SingletonE mInstance = new SingletonE();
//構(gòu)造函數(shù)私有化,使外界無法創(chuàng)建實(shí)例
private SingletonE(){
}
//為外界提供獲取實(shí)例的方法
public static SingletonE getInstance(){
return mInstance;
}
}
也可以通過靜態(tài)代碼塊方法初始化哑了。
不足:浪費(fèi)內(nèi)存空間赘方;代碼不靈活。
5-2-懶漢式
當(dāng)需要使用類的時(shí)候弱左,才去實(shí)例化窄陡。
public class SingletonL {
private static SingletonL mInstance;
private SingletonL(){}
public static SingletonL getInstance(){
if (mInstance == null){ //null判斷
mInstance = new SingletonL();
}
return mInstance;
}
}
不足:多線程中不能保證只創(chuàng)建一次實(shí)例。(多線程并發(fā))
解決方法:加鎖——synchronized
public synchronized static SingletonL getInstance(){
if (mInstance == null){ //null判斷
mInstance = new SingletonL();
}
return mInstance;
}
不足:雖然解決了線程安全的問題拆火,但是方法每次調(diào)用的時(shí)候跳夭,都會進(jìn)行同步檢查,造成效率低们镜。
解決方法:雙重檢查鎖——減少同步檢查范圍
public static SingletonL getInstance(){
if (mInstance == null){
synchronized (SingletonL.class){ //同步檢查
if (mInstance == null){
mInstance = new SingletonL();
}
}
}
return mInstance;
}
不足:mInstance可能未初始化币叹,用戶獲取的對象是空的
原因:Java虛擬機(jī)的指令:
1.給對象分配內(nèi)存;
2.調(diào)用方法初始化對象憎账;
3.將對象與內(nèi)存關(guān)聯(lián)套硼,賦值。
但是Java多線程中胞皱,步驟2和3的執(zhí)行順序不是固定的邪意。
解決方法:volatile的使用 1.防止重排序;2.保證對象可見性反砌。某一線程改了變量雾鬼,短時(shí)間內(nèi)該變量在另一個(gè)線程可能是不可見的,因?yàn)槊恳粋€(gè)線程都有自己的緩存區(qū)宴树。
private static volatile SingletonL mInstance;
5-3-靜態(tài)內(nèi)部類
public class SingletonS {
private SingletonS(){
}
public static SingletonS getInstance(){
return SingletonHolder.mInstance;
}
public static class SingletonHolder{
private static SingletonS mInstance = new SingletonS();
}
}
好處:既保證線程安全策菜,又實(shí)現(xiàn)了懶加載。
5-4-靜態(tài)代碼塊結(jié)合容器(HashMap)
private static Map<String,Object> map = new HashMap<>();
static {
map.put("single",new SingletonS());
}
除了上述的幾種方式外,枚舉也能實(shí)現(xiàn)單例又憨,而且是最簡單的翠霍,但是也存在一種問題——代碼不靈活。所以蠢莺,究竟選擇哪一種方式實(shí)現(xiàn)單例寒匙,還是根據(jù)開發(fā)者自己以及項(xiàng)目需求。
6-Where
Activity管理
參考文章:
https://segmentfault.com/a/1190000018494382
https://blog.csdn.net/qq_25333681/article/details/93662660