程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> java設計模式--單例模式,java設計模式--

java設計模式--單例模式,java設計模式--

編輯:JAVA綜合教程

java設計模式--單例模式,java設計模式--


   單例模式,顧名思義,就是確保某個類在程序中只允許有一個實例。這個類可以自行創建唯一的實例,並且向系統只提供這個唯一的實例。    通常我們說的單例模式有五種:餓漢式,懶漢式,雙重鎖,靜態內部類,枚舉式。其中,餓漢式和懶漢式是最代表的兩種(但不是最優的)。

   首先,餓漢式單例

      它是一種典型的空間換時間的模式,如果對象占用資源較小,不需要延遲加載使用,畢竟餓漢,就是要迅速,裝載類的時候就要創建實例對象。       代碼:      
public class SingletonDemo01 {
	/**
	 * 加載時就把對象創建出來--餓漢式
	 * 類初始化時天然的是線程安全的
	 */
	private static SingletonDemo01 instance=new SingletonDemo01();
	
    private SingletonDemo01(){
	   
   }
    //方法沒有同步,調用效率高
    public static SingletonDemo01 getInstance(){
    	return instance;
    }
}

  

     懶漢式單例

      它是一種典型的時間換空間的模式,對象占用資源較大,需要延遲加載的時候使用,懶漢,就是要用的時候才去創建實例。      代碼:
public class SingletonDemo02 {
	/**
	 * 加載時就不把對象創建出來--懶漢式
	 * 類初始化時天然的是線程安全的
	 */
	private static SingletonDemo02 instance;
	private SingletonDemo02(){
		
	}
	//方法同步,並發效率低(如果不同步,並發量高的時候可能創建多個對象)
	public static synchronized SingletonDemo02 getInstance(){
		if(instance==null){
			instance=new SingletonDemo02();
		}
		return instance;
	}

}

  

     雙重鎖單例

      為了解決時間和空間的問題,可以把同步方法放在判斷力,只在第一次使用同步,之後都不需要浪費時間,基本上做到了空間和時間的協調。但是在JVM低版本底層內部模型的原因,偶爾會出問題,所以基本上不建議使用該方案(該方案可以使用volatile關鍵字,也可以使用synchronize關鍵字實現)。     代碼:   
public class SingletonDemo03 {
	
	private static SingletonDemo03 instance=null;
	private SingletonDemo03(){
		
	}
	public static  SingletonDemo03 getInstance(){
		if(instance==null){
			SingletonDemo03 ins;
			synchronized (SingletonDemo03.class) {
				ins=instance;
				if(ins==null){
					synchronized (SingletonDemo03.class) {
						if(ins==null){
							ins=new SingletonDemo03();
						}
					}
					instance=ins;
				}
			}
		}
		return instance;
	}

}

  

    靜態內部類單例

    同樣是為了解決時間和空間問題,使用靜態內部類可以更好的解決。該方案線程安全(5種方案全是線程安全的),調用效率高,可以延遲加載等都具備。    代碼:    
public class SingletonDemo04 {
	
	
	private SingletonDemo04(){
		
	}
	//類加載的方式天然線程安全
	private static class Singleton04ClassInStance{
		//不存在同步問題,效率高
		private static final SingletonDemo04 instance=new SingletonDemo04();
	}
	//調用的時候才去加載,延遲加載實現
	public static SingletonDemo04 getInstance(){
		return Singleton04ClassInStance.instance;
	}

}

  

   枚舉式單例

     枚舉式應該是餓漢式的高級版本,在5中實現中屬於最高效的一種,簡單,安全,效率超高。但是不能延遲加載。最顯著的特點是,其他四種都可以通過反射和反序列化破解,而枚舉式天然的不能被破解。    代碼:    
public enum SingletonDemo05 {
	/**
	 * 這個枚舉元素本身就是單例
	 */
	INSTANCE;
	/**
	 * 還可以添加自己需要的操作
	 */
	public void singletonOpt(){
		
	}

}

  

  對於五種模式的選擇方案建議:

    若單例對象占用資源少,不需要延遲加載,選擇枚舉式優於餓漢式     若單例對象占用資源大,需要延遲加載,選擇靜態內部類優於懶漢式

 五種模式特點總結:

--主要:
① 餓漢式:線程安全,調用效率高,不可以延遲加載
② 懶漢式:線程安全,調用效率不高,可以延遲加載
-- 其他:
③ 雙重鎖:JVM底層內部模型原因,偶爾會出問題,不建議使用
④ 靜態內部類:線程安全,調用效率高,可以延遲加載
⑤ 枚舉式:線程安全,調用效率高,不可延遲加載。並且可以天然的防止反射和反序列化漏洞。

 對於五種模式的效率對比,使用10個線程,每個線程100000次的調用結果如下:             -- 餓漢式計時:2ms         -- 懶漢式計時:26ms         -- 雙重鎖計時:3ms         -- 靜態內部類計時:2ms         -- 枚舉計時:1ms 更加詳細的代碼以及反射和反序列化破解四種單例模式的代碼請參照github:   https://github.com/LiuJishuai/designPatterns      

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved