java單例模式的寫法

單例模式指的是在內存中只有一個對象 ,這樣咱們想到實現單例模式應該用到static關鍵字多線程

一  懶漢式單例函數

先看下面這個類測試

//懶漢式單例類(我是沒明白這個命名是怎麼來的 與後面的餓漢式單例 的區別是 實例域初始化的時間)
public class Singleton {
      //私有構造方法  通常構造方法都是public 私有說明不能在這個類的外部實例化這個類  
	  private Singleton(){}
	  private static Singleton single=null;  
	    //靜態工廠方法   
	  public static Singleton getInstance(){  
	         if (single == null) {    
	             single = new Singleton();  
	         }    
	        return single;  
	  }   
	  public static void main(String args[])  
	  {  
	        Singleton instance = Singleton.getInstance();  
	        Singleton instance2 = Singleton.getInstance();
	        System.out.println(instance == instance2);
	      
	  }  
	    
}

 首先看到這個類的結構 線程

 這個類只有一個域 這個域是引用類型 這個域被static 修飾 會在類編譯的時候就加載 只不過這個時候是nullcode

 有兩個靜態方法 另一個main方法是我測試用的對象

  打印出的結果是true 說明兩個對象是同一個對象內存

private Singleton() {};
 
 構造函數 跟類名相同的方法是構造函數 構造函數是用來構造一個類的
 構造函數通常是public 能夠在類外調用
 這裏變成private 就能夠防止在另一個類裏面用new的方式建立了

 咱們能夠試試在另一個類裏嗎調用這個構造函數
 public static void main(String[] args) {
		// TODO Auto-generated method stub
       Singleton singleton = new Singleton();
      
}
編譯是報錯的

咱們經過 類名.方法 的方式調用靜態類開發

Singleton.getInstance();
若是實例域是null(第一個調用這個方法)則建立實例域(經過私有構造函數)

2、餓漢式單例get

public  class Singleton {
	  private Singleton() {}  
	  private static final Singleton single = new Singleton();  
	    //靜態工廠方法   
	  public static Singleton getInstance() {  
	        return single;  
	  }    
	  public static void main(String args[])  
	  {  
        Singleton instance = Singleton.getInstance();  
	    Singleton instance2 = Singleton.getInstance();
	    System.out.println(instance == instance2);
	  }  
	    
}

與上面的懶漢式區別是靜態實例域一開始就構造出來了 而懶漢式開始加載的時候是null編譯

也就是餓漢式每次調用時都是同一個對象 類編譯的時候就經過new Singleton() 的方式構造出來 並且在後面不可改變

三 靜態內部類方式

public class Singleton {
    private Singleton() {//構造函數
	}
    private static  class innerClass{ //靜態內部類 編譯後就成了一個單獨的類 Singleton$innerClass 
    	public static final  Singleton instance = new Singleton() ;
    }
    public static final Singleton getinstance(){
    	return innerClass.instance;	
    }
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Singleton instance = Singleton.getinstance();
		Singleton instance1 = Singleton.getinstance();
		System.out.println(instance == instance1);
	}

}

調用單例的方法一樣是 類名.方法 經過內部類的方式調用就是 單例類一開始就構造出來了這跟餓漢式是同樣的 只不過是在內部類中構造的 。

這三個例子都只是實現了單例模式的基本結構  在實際開發中咱們應當在構造函數中實現更多的方法。

另外 網上有不少關於多線程與單例的討論 我只知道第2、三種方法構造出來的單例對象在程序中是不能從新改變賦值的 

有朋友瞭解這方面的問題的能夠說下哈

相關文章
相關標籤/搜索