單例模式:確保乙個類只有乙個例項,並提供乙個全域性訪問點。
用到的設計原則:
1、封裝變化
2、組合優於整合
3、針對介面變成而不是針對實現
4、為互動物件之間的松耦合設計而努力
5、類應該對擴充套件開放,對修改關閉
6、依賴抽象,而不是依賴具體類
最簡單的單例
classsingleton
public
static
singleton getinstantce()
return
instantce;
}}
但是這樣在多執行緒的情況下就會出問題。當兩個執行緒同時第一次獲取單例時,此時instantce還是空,會返回兩個例項。
處理多執行緒單例,最簡單的多執行緒單例
classsingleton
public
static
synchronizedsingleton getinstantce()
return
instantce;
}}
只是多加了乙個synchronized關鍵字。但是這樣,同步效能會降低。以後每次呼叫加保護都是一種累贅。但是如果應用程式可以接受這種額外負擔,比如實際上呼叫這個方法的次數非常少,那就什麼也別做,這個並不會影響多少效能。但是如果頻繁的使用,可以使用下面的方法。
classsingleton
public
static
synchronized singleton getinstantce()
}
這樣jvm在載入這個類的時候就已經建立出來唯一的單例。
或者利用雙重檢索的方法
classsingleton
public
static
synchronized singleton getinstantce() }}
return
instantce;
}}
這裡為什麼裡面還加了乙個判斷,和volatile這個關鍵字有關,volitile可以保證乙個變數在多個執行緒間可見性,如果兩個執行緒同時獲取乙個單例,這時單例為空,第乙個執行緒先判斷,鎖住singleton,第二個執行緒在等待,等待的地方是判斷完為空的位置,第乙個執行緒建立完獲取到了,這時已經不為空了,如果這個地方不判斷還會是在建立乙個,由於volitale保證變數的可見性,第二個執行緒感知到已經例項化完了,就不去建立,直接獲取已經建立好的例項就走了。還有雙重鎖定的方法不能用在jdk1.2之前,現在都1.8了,一般應該不會接觸到這個問題。
還要注意乙個問題,就是不同的類載入器載入這個類的時候還是會建立出不同的例項。如果程式中有多個類載入器,小心這個問題,解決的辦法是自行指定類載入器。
oo設計認為類應該只做一件事,這裡單例類不僅負責管理自己的例項,還在應用程式之間充當角色。儘管如此,由類管理自己的例項的做法還是很常見的,這可以讓整體設計更簡單,不然還需要設計乙個類來管理這個單例類,實在有點繁瑣。
HeadFirst設計模式 單件模式
單件模式確保乙個類只有乙個例項,並提供乙個全域性訪問點。以下為使用 雙重檢查加鎖 在getinstance 中減少使用同步的單件模式 public class singleton 用靜態方法例項化物件,並返回這個例項物件 public static singleton getinstance ret...
HeadFirst設計模式 單例模式
單例模式 我們首先提出的疑問是什麼是單例模式,為什麼需要單例模式?比如有的時候我們對一些物件只用乙個,比如執行緒池。快取等等。如何保障乙個例項的執行呢?或許我們可以使用全域性變數,不過全域性變數只能提供全域性訪問,不能確保只有乙個例項。全域性變數一旦多了,通常有的時候我們自己都忘記了。這點深有感觸。...
Head First設計模式 單例模式
單例模式是所有設計模式中最簡單的模式,也是我們平常經常用到的,單例模式通常被我們應用於執行緒池 快取操作 佇列操作等等。單例模式旨在建立乙個類的例項,建立乙個類的例項我們用全域性靜態變數或者約定也能辦到單例的作用,為什麼我們要用單例模式?接下來我們就從如何形成單例模式,單例模式建立的過程來講解。我們...