java单例模式下面两种方法有什么区别?
方法一:
public class SingleTon {
private static SingleTon singleTon;
private SingleTon(){
}
public synchronized static SingleTon getSingleTon(){
if(singleTon == null){
singleTon = new SingleTon();
}
return singleTon;
}
}
方法二:
public class SingleTon {
private static SingleTon singleTon = new SingleTon();
private SingleTon(){
}
public synchronized static SingleTon getSingleTon(){
return singleTon;
}
}
请教一下这两种方法的区别是什么,哪个更好?
方法二更好,原因就是方法一使用了並發,消耗了性能。
就是懶漢模式和餓漢模式啊,簡單來說就是否是懶加載。這種東西不能說好不好,要看實際場景的。
方法二隻是為並發做了準備,也就是考慮到並發的獲取單例的對象的情況,具體會不會並發訪問是這個類的用戶決定的。
這2種各有各的優缺點。第一種方法,載入快,而取得單例物件較慢,因為使用了if判斷,還要運行時去new物件.第二種,載入類別較慢,取得快。因為靜態成員是在類別載入時初始化的.同時,你的第二個方法沒有必要synchronized , 因為你只是單純的回傳物件的引用,不涉及到new的物件
這是單例模式的倆種設計的方法都採用的同步防止並發出現線程的安全問題但是第一種是懶漢的設計方法第二種是餓漢的設計方法對於程序本身沒有太大的區別就是得到對象的時機有所不同而已
關於單例模式,其實一共有5種方式:
懶漢模式,對應你的第一種程式碼,優點是:延遲加載,缺點是:每次取得實例都需要進行鎖定同步,浪費資源。
餓漢模式,對應你的第二種程式碼,優點是:線程安全,缺點是:一上來就加載,浪費資源。
雙重校驗鎖的懶漢模式。
靜態內部類別的懶漢模式。
Effective Java中推薦使用enum實作單例。
兩者的區別在於,方法一是懶加載,如果此方法不被調用,就不會生成對象,而後者在加載類別的時候就會產生一個實例,無論使用與否。
最典型的懶加載寫法應該是這樣的
這樣比較節省時間,也不會建立新的物件。
此外,在並發情況如果非常高的情況下,可用volatile修飾instance.
------------------------剛沒仔細看你的程式碼,再補充點----------
我發現你給getInstance方法上了同步鎖,這個是完全沒必要的,只有在第一次創建時需要同步,之後的同步完全是浪費時間。