教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

單例中懶漢和惡漢模式的區(qū)別【Java面試題】

更新時間: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é)合項目中的使用

懶漢式的特點是延遲加載,比如配置文件,采用懶漢式的方法。

猜你喜歡

Java中的四種訪問級別 

單例模式教程:單例模式的幾種實現(xiàn)方式 

Java swing是做什么的?有什么作用? 

傳智播客Java高級軟件工程師課程 

0 分享到:
和我們在線交談!