廢話不多說(shuō) 直接上代碼
- 餓漢式
public class MyApplication extends Application {
private MyApplication() {
}
private static MyApplication app = new MyApplication();
public static MyApplication getInstance() {
return app;
}
}
類加載就會(huì)創(chuàng)建實(shí)例授帕,線程安全乖篷。因?yàn)樘摂M機(jī)保證了類只會(huì)加載一次,在裝載類的時(shí)候是不會(huì)并發(fā)的
缺點(diǎn):無(wú)法攜帶參數(shù) 無(wú)法實(shí)現(xiàn)延遲加載
- 懶漢式
public class MyApplication extends Application {
private MyApplication() {
}
private static MyApplication app;
public static MyApplication getInstance() {
if (app == null) {
app = new MyApplication();
return app;
}
return app;
}
}
適合單線程模式 延遲加載
缺點(diǎn):多線程調(diào)用情況下膜赃,會(huì)出現(xiàn)多個(gè)實(shí)例妙真。例如:當(dāng)兩個(gè)線程同時(shí)運(yùn)行到判斷app是否為空的if語(yǔ)句,并且app確實(shí)沒(méi)有創(chuàng)建完畢最疆,那么兩個(gè)線程都會(huì)創(chuàng)建一個(gè)實(shí)例
優(yōu)點(diǎn):可攜帶參數(shù) 延遲加載
- 雙重鎖版本(推薦)
public class MyApplication extends Application {
private MyApplication() {
}
private volatile static MyApplication app;
public static MyApplication getInstance() {
if (app == null) {
synchronized (MyApplication.class) {
if (app == null) {
app = new MyApplication();
return app;
}
}
}
return app;
}
}
注意:
- volatile修飾意思是怕出現(xiàn)多CPU處理出現(xiàn)并發(fā)問(wèn)題 ,可能引發(fā)錯(cuò)亂等多個(gè)實(shí)例的問(wèn)題 建議查下volatile關(guān)鍵字蚤告。
- synchronized修飾意思是必須線程是排隊(duì)一個(gè)一個(gè)進(jìn)去的努酸,處理了多線程的問(wèn)題,同時(shí)加鎖會(huì)很耗時(shí)的操作杜恰,但是不得不為之
- 第一個(gè)IF是判斷需不需要 進(jìn)入加鎖判斷 如果有實(shí)例直接返回實(shí)例,第二個(gè)IF是來(lái)判斷是否為null(因?yàn)橛昧藄ynchronized获诈,不會(huì)出現(xiàn)多線程的情況,所以保證實(shí)例唯一)
- 內(nèi)部靜態(tài)方法類
public class MyApplication extends Application {
private MyApplication() {
}
private static class ChildApp {
private final static MyApplication app = new MyApplication();
}
public static MyApplication getInstance() {
return ChildApp.app;
}
}
注意:
由于內(nèi)部類不會(huì)在加載外部類的時(shí)候進(jìn)行加載心褐,那么這個(gè)也屬于懶加載舔涎。但是這種延遲加載的加載也是class的加載,jvm保證只有一次所以同樣線程安全
優(yōu)點(diǎn):效率比雙重鎖略高
缺點(diǎn):無(wú)法攜帶參數(shù)
- 枚舉(不推薦)
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
枚舉不適用于android逗爹,谷歌說(shuō)的亡嫌。
總結(jié):根據(jù)具體需求使用具體單例,比如涉及多線程操作掘而,并且無(wú)需攜帶參數(shù)就用內(nèi)部靜態(tài)類挟冠,如果是帶參數(shù)那就雙重鎖等。