轉自:http://blog.csdn.net/willamlan/article/details/48596237
設計模式之-------單例模式
在現(xiàn)有的23種設計模式中,可以說單例模式是所有設計模式中最簡單的一種翔横。
單例模式就是說系統(tǒng)中對于某類的只能有一個對象哼转,不可能再出來第二個哮缺。
通過單例模式胎许,自行實例化并向這個系統(tǒng)提供這個單一實例的訪問方法钟沛。
單例模式也是23中設計模式中在面試時少數幾個會要求寫代碼的模式之一驮审。
主要考察的是多線程下單例模式的線程安全性問題译株。
單例模式實例一(不使用同步鎖)
public class Singleton {
private static Singleton sin=new Singleton(); ///直接初始化一個實例對象
private Singleton(){ ///private類型的構造函數,保證其他類對象不能直接new一個該對象的實例
}
public static Singleton getSin(){ ///該類唯一的一個public方法
return sin;
}
}
上述代碼中的一個缺點是該類加載的時候就會直接new 一個靜態(tài)對象出來挡闰,當系統(tǒng)中這樣的類較多時乒融,會使得啟動速度變慢 。現(xiàn)在流行的設計都是講“延遲加載”摄悯,我們可以在第一次使用的時候才初始化第一個該類對象。所以上述這種只適合在小系統(tǒng)愧捕。
單例模式實例二(使用同步方法)
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方式可以方便的實現(xiàn)此中目的。常見的代碼如下:
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 {
}
四、改進型懶漢式(直接滿足線程安全)——通過靜態(tài)內部類實現(xiàn)
在如上的懶漢單例模式中勃黍,對于多線程環(huán)境中宵统。可以通過常見的如synchronized等方式實現(xiàn)線程安全覆获,同時马澈,可以通過Java靜態(tài)內部類的方式實現(xiàn)進一步改進。
常見代碼如下:
public class SingleTon {
// 利用靜態(tài)內部類特性實現(xiàn)外部類的單例
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中靜態(tài)內部類可以訪問其外部類的成員屬性和方法弄息,同時痊班,靜態(tài)內部類只有當被調用的時候才開始首次被加載,利用此特性摹量,可以實現(xiàn)懶漢式涤伐,在靜態(tài)內部類中靜態(tài)初始化外部類的單一實例即可。