一、總結每種單例寫法的優、缺點java
單例類型安全 |
優勢多線程 |
缺點性能 |
餓漢式單例spa |
能夠快速建立實例線程 |
在未使用時就初始化實例,佔用內存空間3d |
懶漢式單例對象 |
只有在使用的時候,纔會建立blog |
須要考慮多線程的安全問題,須要進行雙重校驗保證明例只被建立一次。可是添加鎖後,會有性能問題內存 |
內部類方式單例 |
不須要考慮線程安全,沒有性能問題 |
可經過反射和反序列化方式暴力破壞單例 |
枚舉類方式單例(註冊式單例) |
既能知足單例要求,又沒法被反射和序列化方式破解 |
相對目前最優實現單例方式 |
容器注入方式單例(註冊式單例) |
做爲容器,可存放多種對象的單個實例 |
須要考慮多線程安全問題,添加鎖 |
二、思考破壞單例模式的方式有哪些?而且概括總結
目前破壞單例模式的方式主要有反射和序列化。
反射:普通java類能夠經過反射獲取到構造方法,從而調用構造方法建立新對象。
可是枚舉類方式單例不能經過發射破壞,由於枚舉單例反編譯後能夠看到,枚舉類實際內部沒有無參構造方法。另外,若是反射想經過調用有參構造方法,去建立實例時,反射機制的調用源碼已經作了判斷,判斷當前調用類是不是枚舉,若是是枚舉類,則不容許進行反射調用構造方法建立實例對象。
序列化:序列化方式,當讀取文件流生成對象時,若是是object類型,會去檢查是否含有構造方法,若是有,會從新newInstance建立新對象。若是是枚舉類型,會沒有調用new 對象的動做,而是根據枚舉名稱直接獲取枚舉值。因此枚舉類方式單例不會被反序列化破解,普通單例能夠。
三、梳理內部類的執行邏輯,並畫出時序圖。