轉自:http://blog.csdn.net/willamlan/article/details/48596237
設計模式之-------單例模式
在現有的23種設計模式中,可以說單例模式是所有設計模式中最簡單的一種。
單例模式就是說系統中對于某類的只能有一個對象,不可能再出來第二個。
通過單例模式,自行實例化并向這個系統提供這個單一實例的訪問方法。
單例模式也是23中設計模式中在面試時少數幾個會要求寫代碼的模式之一。
主要考察的是多線程下單例模式的線程安全性問題。
單例模式實例一(不使用同步鎖)
public class Singleton {
private static Singleton sin=new Singleton(); ///直接初始化一個實例對象
private Singleton(){ ///private類型的構造函數,保證其他類對象不能直接new一個該對象的實例
}
public static Singleton getSin(){ ///該類唯一的一個public方法
return sin;
}
}
上述代碼中的一個缺點是該類加載的時候就會直接new 一個靜態對象出來,當系統中這樣的類較多時,會使得啟動速度變慢 。現在流行的設計都是講“延遲加載”,我們可以在第一次使用的時候才初始化第一個該類對象。所以上述這種只適合在小系統。
單例模式實例二(使用同步方法)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static synchronized Singleton getInstance(){ //對獲取實例的方法進行同步
if (instance == null)
instance = new Singleton();
return instance;
}
}
上述代碼中的一次鎖住了一個方法, 這個粒度有點大 ,改進就是只鎖住其中的new語句就OK。就是所謂的“雙重鎖”機制。
單例模式實例三(使用雙重同步鎖)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance(){ //對獲取實例的方法進行同步
if (instance == null){
synchronized(Singleton.class){
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
附注:根據此單一實例產生的時機不同(當然,都是指第一次,也是唯一一次產生此單一實例時),可以將其分為懶漢式、餓漢式和登記式。
一、懶漢式:
其特點是延遲加載,即當需要用到此單一實例的時候,才去初始化此單一實例。如上面的單例模式實例二。
二、餓漢式:
餓漢式的特點是應用中尚未需要用到此單一實例的時候即先實例化。如上面的單例模式實例一。
三、登記式單例模式:
登記式單例模式,一般是通過一個專門的類對各單例模式的此單一實例進行管理和維護。通過Map方式可以方便的實現此中目的。常見的代碼如下:
import java.util.HashMap;
import java.util.Map;
public class SingleTonManager {
private static Map singleTonMap = new HashMap();
public static void main(String[] args) {
// 獲取A類的單例
A a = (A) getInstance(A.class.getName());
// 獲取B類的單例
B b = (B) getInstance(B.class.getName());
}
// 根據類型獲取單例
public static Object getInstance(String className) {
// 判斷singleTonMap中是否有此單例,有則取得后返回,無則添加單例后返回
if (!singleTonMap.containsKey(className)) {
try {
singleTonMap.put(className, Class.forName(className).newInstance());
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return singleTonMap.get(className);
}
}
class A {
}
class B {
}
四、改進型懶漢式(直接滿足線程安全)——通過靜態內部類實現
在如上的懶漢單例模式中,對于多線程環境中。可以通過常見的如synchronized等方式實現線程安全,同時,可以通過Java靜態內部類的方式實現進一步改進。
常見代碼如下:
public class SingleTon {
// 利用靜態內部類特性實現外部類的單例
private static class SingleTonBuilder {
private static SingleTon singleTon = new SingleTon();
}
// 私有化構造函數
private SingleTon() {
}
public static SingleTon getInstance() {
return SingleTonBuilder.singleTon;
}
public static void main(String[] args) {
SingleTon instance = getInstance();
}
}
其主要原理為:Java中靜態內部類可以訪問其外部類的成員屬性和方法,同時,靜態內部類只有當被調用的時候才開始首次被加載,利用此特性,可以實現懶漢式,在靜態內部類中靜態初始化外部類的單一實例即可。