-
1 # Java後端技術棧
-
2 # 前方有隻程式猿
單例模式只要記住一點就是在應用的整個生命週期有且只有一個例項,這也是單例模式的特點。
說著簡單,但實際也不簡單,對於設計模式比較陌生的初學者而言還是有一定複雜度的,因為要考慮應用的時候是否需要延遲載入,是否執行緒安全等等。但相對於其他的設計模式而言,還是相對比較簡單的。單例模式,一般分為懶漢模式和餓漢模式還有相對比較完美的內部靜態類實現方式,還有大神們提倡的列舉方法。下面簡單說下:
餓漢模式餓漢模式,是在類載入的時候就已經完成了例項化,也就是說即使你一直不用這個例項,它也會一直都在佔用著記憶體,雖然有這個缺點,但它是執行緒安全的,保證整個應用的生命週期內只有這一個例項。
懶漢模式懶漢模式說白了就是延遲載入,在初次需要的時候完成例項化,但如果在多執行緒中應用的話,就有可能會造成多次例項化,就不在是單例模式了。但我們也有解決方案,就是加上雙重鎖機制,保證執行緒同步的同時只有一個例項。
內部靜態類方法這個既保證了延遲載入有保證了執行緒同步,相對來說是比較完美的單例模式,因為類在載入時其內部的靜態類是不會載入的,只有在呼叫的時候才載入,同時靜態類也是執行緒安全的。
列舉方法是很多大神推薦的,它在保證只有一個例項、執行緒安全的同時還可以自由序列化,同時呼叫也比較簡單。
以上這些方法的Java參考實現程式碼,網上有很多,因為是手機純手碼,所以這裡僅做簡單介紹。
-
3 # CrazyGIS
Java單例說起來簡單,很多初學者也學起來也認為很簡單,但是深入思考一下,就會發現沒那麼簡單。
單例要考慮到多執行緒併發訪問的問題,就會變得複雜起來。如何保證執行緒安全?比較常見的方法就是使用DCL(Double Check Lock)單例。實現程式碼如下:
這裡還要特別注意,INSTANCE前還需要加上volatile修飾符。為什麼要加這個修飾符呢?這裡就涉及到CPU底層的一些知識了。簡單來說,CPU底層執行指令的時候會對不同的指令進行重排序,我們Java程式碼裡的一行程式碼,在CPU底層可能是多條指令,如果發生了重排序,單例物件例項化過程中可能會把半初始化狀態的物件返回,那麼當前執行緒獲取到的例項與其他執行緒獲取的完全初始化的物件就不一樣了。volatile修飾符,可以防止CPU底層對這一行程式碼的相關指令進行重排序,直到物件完全初始化,保證多個執行緒訪問單例返回的是同一個物件。
所以,看似簡單的問題,其實也不簡單。
回覆列表
Java單例模式應該是那麼多設計模式中較簡單的一批,寫單例模式一般主要考慮執行緒安全和載入是否需要延遲,雙重檢查鎖,列舉,內部類等方式實現,還有餓漢模式和懶漢模式這些結合搞定