摘要:把準備過程紀錄下來,共勉。單例模式有幾種經典寫法,核心思想就是將構造函數私有化,并且通過靜態方法獲取一個唯一的實例。
寫在最前面
導師貪腐出逃美國,兩年未歸,可憐了我。拿了小米和美團的offer,要被延期,offer失效,工作重新找。把準備過程紀錄下來,共勉。
單例模式有幾種經典寫法,核心思想:就是將構造函數私有化,并且通過靜態方法獲取一個唯一的實例。
餓漢式public class Singleton{ private Singleton(){} private static Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; } }懶漢式
public class Singleton{ private Singleton(){} private static Singleton instance = null; public static Singleton getInstance(){ instance = new Singleton(); return instance; } }雙鎖式
public class Singleton{ private Singleton(){ } private volatile static Singleton instance = null; public static Singleton getInstance(){ if(instance == null){ synchonized(Singleton.class){ if(instance == null){ instance = new Singleton(); } } } return instance; } }
關于volatile關鍵字
上面添加了volatile關鍵字,如果沒有volatile關鍵字,在執行instance = new Singleton()時可能會出現問題,偽代碼如下:
inst = allocat(); // 第一步:分配內存 constructor(inst); // 第二步:執行構造函數 instance = inst; // 第三步:賦值,將instance對象指向分配的內存空間(此時instance就不是null了)
由于Java編譯器允許處理器亂序執行,所以第二步和第三步的順序無法保證。如果第三步先執行完畢、第二步未執行時,有另外的線程調用了instance,由于已經賦值,將判斷不為null,拿去直接使用,但其實構造函數還未執行,成員變量等字段都未初始化,直接使用,就會報錯。這就是DCL失效問題,而且很難復現。
對volatile變量的寫操作,不允許和它之前的讀寫操作打亂順序;對volatile變量的讀操作,不允許和它之后的讀寫亂序。
當一個線程要使用共享內存中的volatile變量時,它會直接從主內存中讀取,而不是使用自己本地內存中的副本。當一個線程對一個volatile變量進行寫時,它會將這個共享變量值刷新到共享內存中。
枚舉類本節參考 http://blog.csdn.net/hxpjava1...
public enum Singleton{ instance; }
一個enum常量(這里是INSTANCE)代表了一個enum的實例,enum類型只能有這些常量實例。標準保證enum常量(INSTANCE)不能被克隆,也不會因為反序列化產生不同的實例,想通過反射機制得到一個enum類型的實例也不行的。
避免序列化、反序列化時產生多個實例,有兩種解決方法
拋出異常
/** * prevent default deserialization */ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { throw new InvalidObjectException("can"t deserialize enum"); }
在readResolve()方法中返回實例
ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException; ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
以上兩個方法可以理解為序列化和反序列化過程的入口和出口。writeReplace()返回的對象,就是要被序列化的對象,我們有機會在序列化前把這個對象給換成我們確定好的那個(如果不是“故意搗亂”,暫時沒想到有什么用);而readResolve()方法就是在反序列化完成得到對象前,把這個對象給換成我們確定好的那個。
/** * 反序列化時內存Hook這段代碼 * @return */ private Object readResolve() { return instance; }
靜態內部類本節參考 http://837062099.iteye.com/bl...
內部類的機制來巧妙實現懶漢式單例模式的實現 :Lazy initialization holder class模式。
內部類分為對象級別和類級別,類級內部類指的是,有static修飾的成員變量的內部類。如果沒有static修飾的成員變量的內部類被稱為對象級內部類。
類級內部類相當于其外部類的static成員,它的對象與外部類對象間不存在依賴關系,相互獨立,因此可直接創建。而對象級內部類的實例,是必須綁定在外部對象實例上的。類級內部類只有在第一次被使用的時候才被會裝載。采用類級內部類,在這個類級內部類里面去創建對象實例,能夠讓類裝載的時候不去初始化對象。
當getInstance方法第一次被調用的時候,它第一次讀取SingletonHolder.instance,內部類SingletonHolder類得到初始化;而這個類在裝載并被初始化的時候,會初始化它的靜態域,從而創建Singleton的實例,由于是靜態的域,因此只會在虛擬機裝載類的時候初始化一次,并由虛擬機來保證它的線程安全性。
這個模式的優勢在于,getInstance方法并沒有被同步,并且只是執行一個域的訪問,因此延遲初始化并沒有增加任何訪問成本。
public class Singleton{ private Singleton(){} private static class SingletonHolder{ private static final Singleton instance = new Singleton(); } public static Singleton getInstance(){ return SingletonHolder.instance; } }
本節參考 http://blog.csdn.net/hikvisio...
全文參考 http://blog.csdn.net/u0129753...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/70130.html
摘要:一基礎接口的意義百度規范擴展回調抽象類的意義想不想通過一線互聯網公司面試文檔整理為電子書掘金簡介谷歌求職記我花了八個月準備谷歌面試掘金原文鏈接翻譯者 【面試寶典】從對象深入分析 Java 中實例變量和類變量的區別 - 掘金原創文章,轉載請務必保留原出處為:http://www.54tianzhisheng.cn/... , 歡迎訪問我的站點,閱讀更多有深度的文章。 實例變量 和 類變量...
摘要:作者重慶森林鏈接來源牛客網整個三月份通過牛客網和網友分享的經驗學到了很多東西,現在反饋一下我的面試經歷,希望對同學們有幫助。個人情況大三本方向渣碩,經過實驗室學長內推,于三月底完成面試。校招是實力和運氣的結合,缺一不可。 歡迎關注我的微信公眾號:Java面試通關手冊(堅持原創,分享美文,分享各種Java學習資源,面試題,以及企業級Java實戰項目回復關鍵字免費領取):showImg(h...
摘要:面試官要不你來手寫下單例模式唄候選者單例模式一般會有好幾種寫法候選者餓漢式簡單懶漢式在方法聲明時加鎖雙重檢驗加鎖進階懶漢式靜態內部類優雅懶漢式枚舉候選者所謂餓漢式指的就是還沒被用到,就直接初始化了對象。面試官:我看你的簡歷寫著熟悉常見的設計模式,要不你來簡單聊聊你熟悉哪幾個吧?候選者:常見的工廠模式、代理模式、模板方法模式、責任鏈模式、單例模式、包裝設計模式、策略模式等都是有所了解的候選者:...
摘要:本文介紹一些來自投資銀行的針對三年以上經驗的開發人員面試題。第七題和這兩個方法有什么不同答案本題取自我的投資銀行針對有經驗的開發者的五十個多線程面試題列表。總結以上就是投資銀行通常會出的面試題。 原文地址: https://dzone.com/articles/10... 有為數不少的開發者希望能在像 Barclays、Credit Suisse、Citibank 等等那樣的投資銀行做...
摘要:強大的表單驗證前端掘金支持非常強大的內置表單驗證,以及。面向對象和面向過程的區別的種設計模式全解析后端掘金一設計模式的分類總體來說設計模式分為三大類創建型模式,共五種工廠方法模式抽象工廠模式單例模式建造者模式原型模式。 強大的 Angular 表單驗證 - 前端 - 掘金Angular 支持非常強大的內置表單驗證,maxlength、minlength、required 以及 patt...
閱讀 1603·2023-04-26 01:54
閱讀 1634·2021-09-30 09:55
閱讀 2654·2021-09-22 16:05
閱讀 1872·2021-07-25 21:37
閱讀 2631·2019-08-29 18:45
閱讀 1895·2019-08-29 16:44
閱讀 1893·2019-08-29 12:34
閱讀 1356·2019-08-23 14:02