單例模式

單例模式(Singleton Pattern)

概述

單例設計模式,簡單來說就是一個類始終只能產生一個對象。使用單例模式可以有效節省內存資源,在一些環境配置的類中,一個服務器的軟件啓動以後,只需要加載一次就可以了。例如多個程序讀取一個配置文件時,建議把配置文件封裝成對象。會方便操作其中數據,又要保證多個程序讀到的是同一個配置文件對象,就需要該配置文件對象在內存中是唯一的。使用單例模式保證一個類在內存中的對象唯一性。

單例模式的實現步驟

  1. 私有化構造函數
  2. 創建私有並靜態的本類對象
  3. 定義公有並靜態的方法,返回該對象

餓漢式和懶漢式

餓漢式:在類加載的時候就創建好一個對象,以後每次都返回創建好的這個對象。

//餓漢式
class Single{
    private Single(){
    } //私有化構造函數。
private static Single s = new Single(); //創建私有並靜態的本類對象。
    public static Single getInstance(){ //定義公有並靜態的方法,返回該對象。
        return s;
    }
}

懶漢式:一開始不創建對象,等需要用的時候才創建對象。在需要的時候才佔用資源,懶加載對象。

//懶漢式(lazyload 延遲加載)
class Single{
    private Single(){
    }
private static Single s = null;
    public static Single  getInstance(){
        if(s==null)
            s = new Single ();
        return s;
    }
}

單例模式經典實現方法

方法一:
package com.singleton;
public class Single{
    private Single(){
    } //私有化構造函數。
private static Single s = new Single(); //創建私有並靜態的本類對象。
    public static Single getInstance(){ //定義公有並靜態的方法,返回該對象。
        return s;
    }
}


方法二:
package com.singleton;
public class Single{
    public static final Single s=new Single();
    private Single(){

    }

}

方法三:(枚舉實現)
package com.singleton;
public enum SingleEnum{
    INSTANCT;
}

單例模式的線程安全問題

在Web項目中,每個 HTTP Request 請求到 J2EE的容器上後都創建了一個線程,每個線程都要創建同一個單例對象。如果同時有多個線程訪問程序,可能會出現多個對象實例,會造成業務邏輯混亂,數據不不一致等問題。
解決方法:
1) 使用同步方法:
public static synchronized Single getInstance()
2) 使用同步代碼塊:
synchronized (Single.class)


//使用同步代碼塊
class Single {
    private static Single s = null; 
    //1) 把構造方法設置成私有的
    private Single() {

    }
    //2) 提供一個公共的靜態的方法產生對象
    public static Single getInstance() {
        if (s==null) {
            synchronized (Single.class) {  //判斷同步鎖,是需要消耗資源
                if (s == null) {  //必須加上
                    try {
                        Thread.sleep(5);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    s = new Single();
                }
            }
        }
        return s;
    }
    }


//使用同步方法
 class Single {
private static final Single s= new Single();
// 限制住不能直接產生一個實例
private Single(){
}
public synchronized static Single getInstance(){
return s;
}
}
發佈了33 篇原創文章 · 獲贊 2 · 訪問量 7905
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章