經典設計模式(二):單例模式
阿新 • • 發佈:2018-12-03
版權宣告
最近很多爬蟲來我部落格爬文章,轉載可以,但請保留原文出處及版權宣告,即便是在中國
- 本文作者:低調小熊貓
- 本文連結:https://aodeng.cc/archives/dan-li-mo-shi
- 版權宣告:本文采用知識共享署名 4.0 國際許可協議進行許可。轉載-非商用-非衍生-保持署名,商業轉載請聯絡作者本人qq:2696284032
單純的廣告
個人部落格:https://aodeng.cc
微信公眾號:低調小熊貓
QQ群:756796932
簡介
單例模式確保一個類只有一個例項,並提供一個全域性訪問點,上班偷偷寫的文章,所以請仔細看註釋
使用
懶漢式
/** * @program:hope * @author:aodeng * @blog:低調小熊貓(https://aodeng.cc) * @微信公眾號:低調小熊貓 * @create:2018-11-15 13:20 **/ public class SingleObject { /**===============懶漢式(那個取的名字,本人表示根本記不住)英文名,叫 lazy loading,也就是延遲載入===============**/ private static SingleObject instance; /**讓建構函式為 private,這樣該類就不會被例項化**/ private SingleObject(){} /**但是上面程式碼會有一個問題,當多個執行緒同時呼叫 getInstance() 方法時,可能會產生多個instance 例項,因此這種方式並不是真正的單例。 為了解決執行緒安全問題,我們只需要在getInstance() 方法上使用synchronized 關鍵字給執行緒加鎖即可 synchronized 的作用是加鎖,當多個執行緒同時呼叫getInstance() 時,只有一個執行緒能進入,其他執行緒會等待進入的執行緒出來之後在一一進入, 這樣就能保證instance 例項是唯一的。這才是真正的單例,不過這並不是完美的解決方案,只要是鎖,必然有效能損耗問題。而且對於上面的程式碼, 其實我們只需要線上程第一次訪問時加鎖即可,之後並不需要鎖,鎖給我們帶來了系統資源浪費**/ public static synchronized SingleObject getInstance(){ if (null == instance){ instance=new SingleObject(); } return instance; } private String name="低調小熊貓"; public String getName() { return name; } public void setName(String name) { this.name = name; } }
餓漢式
/** * @program:hope * @author:aodeng * @blog:低調小熊貓(https://aodeng.cc) * @微信公眾號:低調小熊貓 * @create:2018-11-15 13:34 **/ public class SingleObject2 { /**=======餓漢式(低調小熊貓表示還是記不住)新的解決方案是not lazy loading,在類載入時就建立好了例項,解決懶漢式鎖給我們帶來了系統資源浪費===============**/ private static SingleObject2 instance=new SingleObject2(); private SingleObject2(){} public static SingleObject2 getInstance(){ return instance; } /**這種方式就可以保證例項唯一了**/ private String name="低調小熊貓2"; public String getName() { return name; } public void setName(String name) { this.name = name; } }
double-checked locking (雙重檢查加鎖)
/**
* @program:hope
* @author:aodeng
* @blog:低調小熊貓(https://aodeng.cc)
* @微信公眾號:低調小熊貓
* @create:2018-11-15 13:45
**/
public class SingleObject3 {
/**=======還有一種叫 double-checked locking (雙重檢查加鎖)==============**/
/**這種方式主要用到兩個關鍵字volatile 和 synchronized,synchronized 的作用是加鎖,就不再多說,而volatile 關鍵字許多人不瞭解,沒關係,我們先看程式碼**/
private volatile static SingleObject3 instance;
private SingleObject3(){}
private static SingleObject3 getInstance(){
if (null == instance) {
synchronized (SingleObject3.class){
if (null == instance){
instance =new SingleObject3();
}
}
}
return instance;
}
/**volatile 關鍵字簡單來說就是可以保證instance變數在被其中一個執行緒new出來時,其他執行緒可以立即看到結果並正確的處理它。對volatile 有興趣的朋友可以自行度娘
* 這種方式的單例模式可以大大的減少鎖所帶來的效能損耗**/
private String name="低調小熊貓3";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
TestMain
/**
* @program:hope
* @author:aodeng
* @blog:低調小熊貓(https://aodeng.cc)
* @微信公眾號:低調小熊貓
* @create:2018-11-15 13:23
**/
public class TestMain {
public static void main(String[] args) {
/**======單例使用========**/
//懶漢式
SingleObject singleObject=SingleObject.getInstance();
//餓漢式
SingleObject2 singleObject2=SingleObject2.getInstance();
//雙重檢查加鎖,額,是不是很尷尬,我不知道怎麼用這個
//SingleObject3 singleObject3=SingleObject3.
System.out.println(singleObject.getName());
System.out.println(singleObject2.getName());
/**
* 優點
使用單例模式,物件在記憶體中只有一個例項,並且無需頻繁的建立和銷燬物件,大大的減少了效能的損耗
缺點:懶得打字了,可以忽略
個人喜歡使用餓漢式單例,也就是not lazy loading,沒有為什麼,就是這種程式碼少點,嘿嘿
**/
}
}
原始碼連結
https://github.com/java-aodeng/hope
- 本文作者: 低調小熊貓
- 本文連結: https://aodeng.cc/archives/dan-li-mo-shi
- 版權宣告: 本部落格所有文章除特別宣告外,均採用CC BY-NC-SA 3.0 許可協議。轉載請註明出處!