天天看點

singleton

單例模式3要素“

    1.構造私有,防止外部直接new對象

    2.定義靜态成員類變量

    3.提供靜态方法

餓漢式:

優點:

     1.線程安全,因為類加載的時候已經完成了單例建立

     2.是以擷取單例的時候不需要加鎖

 缺點:

      單例的建立不是延遲加載,無論你用與否,都已經被加載,是不是有點浪費資源?

懶漢式:

     1.延遲加載,沒用到時不加載

     2.為了線程安全,我們在擷取執行個體的方法添加了synchronized

缺點:

     1.getsingleton方法為synchronized,無論單例是否已經建立,所有來擷取單例的線程都得排隊等待,調用頻繁的話撞鎖嚴重

雙重檢測:

 該方案對于懶漢式進一步改進,對象存在時直接擷取 無需上鎖,隻有對象不存在需要建立時才進行加鎖

     1.延遲加載,節省資源

     2.線程安全

     3.撞鎖幾率小,隻有初次建立才會有撞鎖可能

問題:

你上面的方案能防止reflection構造對象嗎? 不能,如何解決呢?

首先對于reflection構造對象的問題,隻需要在預設構造函數在對象存在的情況下被再次調用時抛出異常

其次能防止反序列化構造對象嗎?不能,如何解決呢? 重寫readresolve方法!

4.靜态内部類

java 再建立外部類的時候不會建立内部類執行個體,隻有在外部類使用到内部類的時候才會建立内部類執行個體

難道靜态内部類建立就是線程安全的嗎?為啥這個時候不需要加synchronized? 這個要涉及到java虛拟機的工作原理,菜鳥暫時不做過多研究。總之多個線程在同時進行靜态内部類建立的時候,虛拟機會保證隻有一個線程可以執行cinit方法,其他線程都阻塞等待。

 5.枚舉

還有一種方式就是枚舉

那究竟什麼時候用到單例呢?

1.網站計數器

2.資料庫連接配接池

3.日志元件

4.多線程的線程池

繼續閱讀