設計模式之單例模式及應用demo


單例模式是創建型模式之一。

單例模式顧名思義是單例的,也就是只有一個實例化對象,這都來源於它的私有化構造函數。

單例模式特點:
  1、單例類只能有一個實例。
  2、單例類必須自己創建自己的唯一實例。
  3、單例類必須給所有其他對象提供這一實例

單例模式的應用場景:Windows的Task Manager(任務管理器);網站的計數器; 多線程的線程池的設計; Web應用的配置對象的讀取(由於配置文件是共享的資源)。

單例模式的五種實現方法:

在看實現方法之前,要先了解一些java的知識:1、初始化順序依次是:(靜態變量、靜態初始化塊)–>(普通變量、初始化塊)–> 構造器;如果有父類,則順序是:父類static方法 –> 子類static方法 –> 父類構造方法- -> 子類構造方法 。     

2、靜態變量特點:static變量值在類加載的時候分配空間,以后創建類對象的時候不會重新分配,后面根據需要是可以再次賦值的。公共性,就是說,一個類的靜態成員,它是屬於大伙的,所有的類對象共享的,不像成員變量是自己的。


 

1、餓漢模式

public class Singleton {
    // 私有構造
    private Singleton() {}

    private static Singleton instance = new Singleton();

    // 靜態工廠方法,方法沒有同步塊,所以效率高。
    public static Singleton1 getInstance() {
        return  instance;
    }
}

  餓漢式在類創建的同時就已經創建好一個靜態的對象供系統使用,以后不再改變,所以天生是線程安全的。

2、懶漢模式

public class Singleton {
    private static Singleton instance;
    private Singleton (){}
    //使用的同步鎖,降低了效率,但是在多線程可以防止創建多個實例
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

餓漢就是類一旦加載,就把單例初始化完成,保證getInstance的時候,單例是已經存在的了,

而懶漢比較懶,只有當調用getInstance的時候,才回去初始化這個單例。

 

3、雙重檢測模式

public class Singleton {
    public static volatile Singleton singleton = null;

    private Singleton(){}

    public static Singleton getInstance(){
        if(singleton == null){ 
           synchronize (Singleton.class){
               if( singleton == null ) { 
                   singleton = new Singleton();
               }
        }
        return singleton;
    }
}
  當兩個線程執行完第一個 singleton == null 后等待鎖, 其中一個線程獲得鎖並進入synchronize后,實例化了,然后退出釋放鎖,
另外一個線程獲得鎖,進入又想實例化,會判斷是否進行實例化了,如果存在,就不進行實例化了。 

4、靜態內部類

public class Singleton { 
    // 靜態內部類LazyHolder
    private static class LazyHolder {  
       private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
       return LazyHolder.INSTANCE;  
    }  
} 
 此方法既實現了線程安全,又避免了同步帶來的性能影響。
還有就是類似的靜態代碼塊實現:
public class Singleton{
    
    // 私有構造
    private Singleton() {}
    
    private static Singleton single = null;

    // 靜態代碼塊
    static{
        single = new Singleton();
    }
    
    public static Singleton getInstance() {
        return single;
    }
}

5、枚舉類

public class SingletonFactory {
    
    // 內部枚舉類
    private enum EnmuSingleton{
        Singleton;
        private Singleton singleton;
        
        //枚舉類的構造方法在類加載是被實例化 
        private EnmuSingleton(){
            singleton = new Singleton();
        }
        public Singleton getInstance(){
            return singleton;
        }
    }
    public static Singleton getInstance() {
        return EnmuSingleton.Singleton.getInstance();
    }
}

class Singleton{
    public Singleton(){}
}

 下面是一個單例模式使用的demo 餓漢模式

public class TestSingleton {
	
	String name = null;
	private TestSingleton() {
	}
 
	private static TestSingleton instance = new TestSingleton();
 
	public static TestSingleton getInstance() {
           return instance;
	}
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public void print() {
		System.out.println("the name is " + name);
	}

	public static void main(String[] args) {
		// TODO 自動生成的方法存根
		TestSingleton ts1 = TestSingleton.getInstance();
		ts1.setName("12345");
		TestSingleton ts2 = TestSingleton.getInstance();
		ts2.setName("56789");
		
		ts1.print();
		ts2.print();		
		if(ts1 == ts2){
			System.out.println("創建的是同一個實例");
		}else{
			System.out.println("創建的不是同一個實例");
		}

	}

}

  

 


免責聲明!

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



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