JAVA的單例模式與延時加載


延遲加載(lazy load)是(也稱為懶加載),也叫延遲實例化,延遲初始化等,主要表達的思想就是:把對象的創建延遲到使用的時候創建,而不是對象實例化的時候創建。延遲加載機制是為了避免一些無謂的性能開銷而提出來的,這種方式避免了性能的浪費。所謂延遲加載就是當在真正需要數據的時候,才真正執行數據加載操作。可以簡單理解為,只有在使用的時候,才會發出sql語句進行查詢。

所謂延時加載技術,就是優化內存資源的利用效率,你要用什么,在用的時候再給你,而不是你遲點會用到的時候就馬上給你。

當創建一個對象的子對象開銷比較大時,而且有可能在程序中用不到這個子對象,那么就可以考慮用延遲加載的方式來創建子對象。另外就是當一個程序啟動時,需要創建多個對象,但僅有幾個對象需要立即使用,那么可以將一些不必要的初始化工作延遲到使用的時候。這樣可以提高程序的啟動速度。

 

 

 

 

實例一:

public Class Singleton

{

private static Singleton instance;

private Singleton(){ } //私有無參構造

 

public static Singleton getInstance(){

If(instance==null){

Instance=new Singleton();

}

Return instance;

}

}

構造函數私有,方法靜態。

問題:無法保證線程安全,當有多個線程同時訪問getInstance的時候,此時若對象為空,就會出現會多個線程同時產生多個Singleton對象。

此時我們可以修改一下上面的代碼,如實例二

 

實例二:

publicclass Singleton
{
privatestatic Singleton instance;
privatestaticobject _lock=newobject();

private Singleton()
{

}

publicstatic Singleton GetInstance()
{
if(instance==null)
{
lock(_lock)
{
if(instance==null)
{
instance=new Singleton();
}
}
}
return instance;
}
}

上述代碼使用了雙重鎖方式較好地解決了多線程下的單例模式實現。先看內層的if語句塊,使用這個語句塊時,先進行加鎖操作,保證只有一個線程可以訪問該語句塊,進而保證只創建了一個實例。再看外層的if語句塊,這使得每個線程欲獲取實例時不必每次都得加鎖,因為只有實例為空時(即需要創建一個實例),才需加鎖創建,若果已存在一個實例,就直接返回該實例,節省了性能開銷。

 

實例三:

public class Singleton
{
private static Singleton instance = new Singleton();
private Singleton() { }

public static Singleton getInstance()

{

return instance;
}

}

這個方法保證了在第一次加載的時候實例被初始化,且保證了線程安全。但是為進一步要求,我們想要在使用的時候才才初始化Singleton對象,及延遲加載。那么可以使用實例四方法。

 

實例四:

public class Singleton {
    private Singleton() { };

   private static class SingletonHolder {
       static Singleton instance = new Singleton();
  }

public static Singleton getInstance() {
       return SingletonHolder.instance;
   }
   public static void main(String [] args){
      Singleton.getInstance();
   }
}

該方法中Singleton有一個靜態內部類SingletonHolder,內部類在外部加載的時候並不會加載,在有在調用getInstance才回加載。另外SingletonHolder類使用Private修飾以確保外部類不能訪問。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM