Java 設計模式之單例

2021-08-19 11:03:11 字數 2827 閱讀 9632

單例模式又名單子模式。是一種非常常見的設計模式。我們在運用這模式的時候,基本是為了確保整個系統中只有乙個例項。

避免頻繁的建立銷毀物件,可以提高效能;

避免對共享資源的多重占用,簡化訪問;

為整個系統提供乙個全域性訪問點。

1、餓汗式

/**

* 餓漢式單例

*/public class singleton1

//獲取單例

public static singleton1 getinstance()

}

2、懶漢式

public class singleton2 

//獲取單例

public static singleton2 getinstance()

return singleton2;

}}

總結:

1、餓汗式單例在這個類被載入的時候就會去new 乙個靜態例項。因為我們知道static修飾的變數 整個生命週期只建立一次 。所以也就確保了整個系統中只有它乙個例項。

2、懶漢式單例是當我們需要的時候去建立例項。

從速度和反應時間上來說,餓汗式更好。但從資源利用效率上來說,懶漢式更好。   

我們先看如下**:

public class test 

}static class mythread extends thread catch(interruptedexception e)}}

}

輸出結果:

hashcode-----2136701979

hashcode-----2136701979

hashcode-----2136701979

hashcode-----2136701979

hashcode-----2136701979

hashcode-----2136701979

hashcode-----2136701979

hashcode-----2136701979

hashcode-----2136701979

hashcode-----2136701979

證明:餓汗式單例 在多執行緒下也是安全的

我們再看看懶漢式單例在多執行緒下的表現

hashcode-----100758745

hashcode-----2075012821

hashcode-----2075012821

hashcode-----2075012821

hashcode-----2075012821

hashcode-----2075012821

hashcode-----2075012821

hashcode-----2075012821

hashcode-----2075012821

hashcode-----2075012821

證明: 懶漢式單例在多執行緒下是不安全的:

總結:其實道理很簡單。餓汗式單例 因為在類載入的時候,就已經建立了為一得例項,所以多執行緒下肯定是執行緒安全的。

而懶漢式是在呼叫的時候去建立的。當我們**走到if(singleton2 == null)判斷語句的時候,多執行緒的環境下。就有可能同時走到這塊,並且同時建立多個例項。

1、第一種寫法:

public class singleton2 

//獲取單例

public static synchronized singleton2 getinstance()

return singleton2;

}}

這種寫法和上面的懶漢式寫法的唯一區別 使用了synchronzied修飾了整個方法,這樣寫保證了臨界資源的互斥訪問,從而保證了執行緒安全。

public class singleton2 

//獲取單例

public static singleton2 getinstance()

return singleton2;}}

}

這種寫法相對於上面寫法,效率仍很差。

3、第三種寫法

public class singleton2 

private static class singleton2holder

//獲取單例

public static singleton2 getinstance()

}

public class singleton2 

//獲取單例

public static singleton2 getinstance()}}

return singleton2;

}}

首先我們需要弄清楚 new singleton2()這個操作是乙個非原子操作,其次我們要知道jvm到底做了哪些操作

1、 在記憶體中分配一塊位址

2、初始化物件

3、使sinleton2 指向記憶體中的位址

編譯器有可能會出現指令重排的問題,有可能先後順序變成了1,3,2。當執行緒1去調getinstance方法獲取單例的時候,走到3時,這是執行緒2也來獲取單例,這時候進入判斷singleton2==null 判斷的時候,其實singleton2只是不為null ,但並未初始化完成。

那執行緒2獲取的例項是乙個有問題的例項,會是應用程式奔潰。所以造成這種現象的原因是指令重排。

我們又知道volatile是能完美解決這一方案的。所以需要新增修飾。

java之單例設計模式

單例設計模式 乙個類有且僅有乙個例項,而且自行例項化然後提供給其他類。單例設計模式分為兩類 餓漢式和飽漢式。餓漢式指的是在類載入時建立。懶漢式指的是在使用的時候進行判斷,如果需要再建立。餓漢式的 如下 public class singlepattern public static singlepa...

java設計模式之單例

單例模式與工具類 提到單例設計模式就不得不提工具類了,在網上有許多關於它們的說法,在這裡我說說自己的看法,從核心的角度來說,單例工具類的區別在於 1.1 單例的思想特點 2 餓漢式 public class singleton 在類載入的時候,建立乙個靜態的物件,乙個類只會載入一次 private ...

java之單例設計模式

單例設計模式 保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。要實現單例,需要 1 構造方法私有化 2 宣告乙個本類物件 3 給外部提供乙個靜態方法獲取物件例項 兩種實現方式 1 餓漢式 2 懶漢式 餓漢式 public class demo1 餓漢式 class singleton1 pr...