1. 程式人生 > >設計模式2:單例模式

設計模式2:單例模式

單例模式

確保一個類中只有一個例項,自行例項化並向整個系統提供這個例項,這個類被稱為單例類,它提供全域性的訪問方法

特點

在類中只有一個例項,並提供一個靜態的getInstacne()方法用於外界唯一訪問這個例項

防止在外部對其例項化,建構函式私有化

在單例類內部定義了一個Singleton型別的靜態物件,作為外部共享的唯一例項

舉例

windows作業系統中的工作管理員,回收站等,在系統中都只有一個例項,是典型的的單例模式

五種實現方式

餓漢式(執行緒安全)

顧名思義,既然是惡漢,肯定是飢不擇食啦,所以不管三七二十一,在類載入的時候就把例項給創建出來咯

//餓漢式
public class SingletonDemo2 {
	
	private static SingletonDemo2 instance = new SingletonDemo2();
	
	//私有化構造器
	private SingletonDemo2(){
		
	}
	
	public static SingletonDemo2 getInstance(){
		
		return instance;
		
	}

}

優點:不用考慮執行緒同步問題

缺點:如果getInstance方法,則會造成資源浪費

懶漢式(執行緒安全,延時載入)

建立例項這麼麻煩的事情。。當然要拖到最後一刻啦,等需要用到例項的時候再建立

//懶漢式
public class SingletonDemo1 {
	
	private static SingletonDemo1 instance;
	
	//私有化構造器
	private SingletonDemo1(){
		
	}
	
	public static synchronized SingletonDemo1 getInstance(){
		
		if(instance == null){
			instance = new SingletonDemo1();
		}
		
		return instance;
	}

}

優點:延遲載入,資源利用率提高

缺點:同步造成併發效率低

雙重加鎖機制

在之前的懶漢式中,它的缺點非常明顯,為了保證在多執行緒的工作下能正常工作,它進行了同步,下一個執行緒想要獲取物件,就必須等待上一個執行緒釋放鎖之後,才可以繼續執行。但是百分之99.9的情況下都是不需要同步的,所以它的效率是非常低的,於是我們進行優化,避免整個方法被鎖,只對需要鎖的程式碼部分加鎖,可以提高執行效率。

//雙重校驗鎖
public class SingletonDemo3 {
	
	private volatile static SingletonDemo3 instance;
	
	private SingletonDemo3(){
		
	}
	
	public static SingletonDemo3 getInstance(){
		
		if(instance == null){
			synchronized (SingletonDemo3.class) {
				if(instance == null){
					instance = new SingletonDemo3();
				}
			}
		}
		
		return instance;
	}

}

靜態內部類實現

//靜態內部類
public class SingletonDemo4 {
	
	
	private static class SingletonClassInstance { 
		private static final SingletonDemo4 instance = new SingletonDemo4(); 
	} 

	
	private SingletonDemo4(){
		
	}
	
	public static SingletonDemo4 getInstance(){
		
		return SingletonClassInstance.instance;
		
	}
	
}

外部類沒有static屬性,則不會像餓漢式那樣立即載入物件。

只有真正呼叫getInstance(),才會載入靜態內部類。載入類時是執行緒 安全的。 instance是static final型別,保證了記憶體中只有這樣一個例項存在,而且只能被賦值一次,從而保證了執行緒安全性.

兼備了併發高效呼叫和延遲載入的優勢!

列舉

public enum SingletonDemo5 {
    /**
    * 定義一個列舉的元素,它就代表了Singleton的一個例項。
    */
   INSTANCE;
   /**
    * 單例可以有自己的操作
    */
   public void singletonOperation(){
       //功能處理
   }
}

•優點:

–實現簡單

–列舉本身就是單例模式。由JVM從根本上提供保障!避免通過反射和反序列化的漏洞!

•缺點:

–無延遲載入

總結

篇中對單例模式進行了簡單介紹,同時介紹了它的五種典型的實現方式