天天看點

Java面向對象之Java單例模式

适用場景:

1、 需要生成唯一序列的環境;

2、 需要頻繁執行個體化然後銷毀的對象;

3、 建立對象時耗時過多或者耗資源過多,但又經常用到的對象;

4、 友善資源互相通信的環境。

Java 單例模式有五種實作方式:

一、 餓漢式:

特點:線程安全,調用效率高,但是不能延時加載。

示例代碼:

public class SingletonOne {	
	//第2步,用一個私有的靜态變量來存自身
	//執行個體化自身SingletonOne這個類。final保證安全
	private static final SingletonOne INSTANCE=new SingletonOne();		
	//第1步、隐藏(私有)構造器
	private SingletonOne(){
		
	}	
	//第3步,建立靜态工廠方法 ,讓外部可以擷取執行個體(INSTANCE)
	public static SingletonOne getInstance(){
		return INSTANCE;
	}
}
           

二、 懶漢式:

特點:線程安全,調用效率不高,但是能延時加載

示例代碼:

public class SingletonTwo {
	//類初始化時,不初始化這個對象(延時加載,真正用的時候再建立)
	private static SingletonTwo instance;
	// 私有化構造器
	private SingletonTwo() {

	}
	//synchronized方法同步,調用效率低
	// 建立靜态工廠方法 ,讓外部可以擷取執行個體,需要用的時候才會new
	public static synchronized SingletonTwo getInstance() {
		if (instance == null) {
			instance = new SingletonTwo();
		}
		return instance;
	}
}
           

三、 Double CheckLock實作單例:

Double CheckLock也就是雙重鎖判斷機制(由于JVM底層模型原因,偶爾會出問題,不建議使用),是在懶漢式單例上發展而來

示例代碼:

public class SingletonThree {	
    private volatile static SingletonThree instance;    
    //私有化構造器
    private SingletonThree() {
    }
    //靜态工廠方法,雙重鎖判斷機制
    public static SingletonThree newInstance() {
        if (instance == null) {
            synchronized (SingletonThree.class) {
                if (instance == null) {
                    instance = new SingletonThree();
                }
            }
        }
        return instance;
    }
}
           

四、 靜态内部類模式:

特點:線程安全,調用效率高,可以延時加載

示例代碼:

public class SingletonFour {
	// 靜态内部類
	private static class SingletonClassInstance {
		private static final SingletonFour instance = new SingletonFour();
	}
	// 私有化構造器
	private SingletonFour() {

	}
	//靜态工廠方法
	public static SingletonFour getInstance() {
		return SingletonClassInstance.instance;
	}
}
           

五、 枚舉類:

特點:線程安全,調用效率高,不能延時加載,可以天然的防止反射和反序列化調用

示例代碼:

public class SingletonFive {	
	//私有化構造器
	private SingletonFive(){
		
	}
	//使用枚舉
	private static enum Singleton{		
		INSTANCE;		
		private SingletonFive singleton;
        //JVM會保證此方法絕對隻調用一次
        private Singleton(){
            singleton = new SingletonFive();
        }
        public SingletonFive getInstance(){
            return singleton;
        } 
	}	
	//靜态工廠方法
	public static SingletonFive getInstance(){
		return Singleton.INSTANCE.getInstance();
	}	
}
           

注意:如何選擇?

單例對象占用資源少,不需要延時加載時:枚舉好于餓漢;

單例對象占用資源多,需要延時加載時:靜态内部類好于懶漢式。

總結:

單例對象(Singleton)是一種常用的設計模式。在Java應用中,單例對象能保證在一個JVM中,該對象隻有一個執行個體存在。

餓漢式單例:直接将對象定義出來;

懶漢式單例:隻給出變量,并不将其初始化(先定義,但是不建立對象)。

單例模式解決的問題:保證一個類在記憶體中的對象唯一性。

比如:多程式讀取一個配置檔案時,建議配置檔案封裝成對象。會友善操作其中資料,又要保證多個程式讀到的是同一個配置檔案對象,就需要該配置檔案對象在記憶體中是唯一的。

Runtime()方法就是單例設計模式進行設計的。

如何保證對象唯一性呢?

思想:

1,不讓其他程式建立該類對象。

2,在本類中建立一個本類對象。

3,對外提供方法,讓其他程式擷取這個對象。

步驟:

1,因為建立對象都需要構造函數初始化,隻要将本類中的構造函數私有化,其他程式就無法再建立該類對象;

2,就在類中建立一個本類的對象;

3,定義一個方法,傳回該對象,讓其他程式可以通過方法就得到本類對象。(作用:可控)

代碼展現:

1,私有化構造函數;

2,建立私有并靜态的本類對象;

3,定義公有并靜态的方法,傳回該對象。