更新時間:2020年09月29日10時27分 來源:傳智播客 瀏覽次數(shù):
(1)問題分析:
主要考察懶漢和餓漢模式在創(chuàng)建時的區(qū)別以及分別在什么情況下使用懶漢模式,什么情況下使用餓漢模式。
懶漢模式:在類加載的時候不被初始化。
餓漢模式:在類加載時就完成了初始化,但是加載比較慢,獲取對象比較快。
餓漢模式是線程安全的,在類創(chuàng)建好一個靜態(tài)對象提供給系統(tǒng)使用,懶漢模式在創(chuàng)建對象時不加上synchronized,會導(dǎo)致對象的訪問不是線程安全的。
(2)核心答案講解:
餓漢式:
public class Singleton{
? private static Singleton singleton = new Singleton ();
? private Singleton (){}
? public static Singleton getInstance(){return singletion;}
? }
懶漢式:
public class Singleton{
? private static Singleton singleton = null;
? public static synchronized synchronized getInstance(){
? if(singleton==null){
? singleton = new Singleton();
? }
? return singleton;
? }
? }
餓漢式是線程安全的,在類創(chuàng)建的同時就已經(jīng)創(chuàng)建好一個靜態(tài)的對象供系統(tǒng)使用,以后不在改變
懶漢式如果在創(chuàng)建實例對象時不加上synchronized則會導(dǎo)致對對象的訪問不是線程安全的。
從實現(xiàn)方式來講他們最大的區(qū)別就是懶漢式是延時加載,是在需要的時候才創(chuàng)建對象,而餓漢式在虛擬機啟動的時候就會創(chuàng)建。
(3)問題擴展
懶漢式不會預(yù)先創(chuàng)建對象,只在第一次調(diào)用時才創(chuàng)建對象,但是多線程并發(fā)執(zhí)行的時候就很容易出現(xiàn)安全隱患,比如說第一個線程在判斷newInstance == null時,還沒有new出實例時,第二個線程也進來,判斷的newInstance也是null,然后也會new出實例,這就不符合單例模式了, 所以需要加鎖。使用synchronized關(guān)鍵字加鎖能解決安全問題,但是加鎖同時會出現(xiàn)一個問題,那就是每次都需要判斷鎖,這樣性能就會降低,所以為了提高性能,我們應(yīng)該盡量減少鎖判斷的次數(shù),加上雙重判斷。
//靜態(tài)工廠方法、單鎖
public synchronized static SingletonTest2 getInstance1() {
? if (single2==null) {
? single2 = new SingletonTest2();
? }
? return single2;
}
?
//靜態(tài)工廠方法、雙重鎖
public static SingletonTest2 getInstance2() {
? if (single2==null) {
? synchronized (SingletonTest2.class) {
? if (single2==null) {
? single2 = new SingletonTest2();
? }
? }
? }
? return single2;
}
(4)結(jié)合項目中的使用
懶漢式的特點是延遲加載,比如配置文件,采用懶漢式的方法。
猜你喜歡