1. 程式人生 > >Java基礎系列-單例的7種寫法

Java基礎系列-單例的7種寫法

原創文章,轉載請標註出處:[https://www.cnblogs.com/V1haoge/p/10755322.html](https://www.cnblogs.com/V1haoge/p/10755322.html) ## 一、概述 Java中單例有7種寫法,這個是在面試中經常被問到的內容,而且有時候還要求手寫單例實現方式。所以我們有必要認真的瞭解一下這七種寫法。 ## 二、七種實現 ### 2.1 懶漢式——執行緒不安全 ```java public class SingletonOne { public static SingletonOne singleton; private SingletonOne() {} public static SingletonOne getSingleton() { if (singleton == null) return new SingletonOne(); return singleton; } } ``` > 懶漢式實現了懶載入,但是執行緒不安全,基本不會使用。 ### 2.2 懶漢式——執行緒安全 ```java public class SingletonTwo { public static SingletonTwo singleton; private SingletonTwo() {} public static synchronized SingletonTwo getSingleton() { if (singleton == null) return new SingletonTwo(); return singleton; } } ``` > 在第一種的基礎上加了個synchronized,保證執行緒安全,同時實現了懶載入,只是效率不高。 ### 2.3 餓漢式 ```java public class SingletonThree { public static SingletonThree singleton = new SingletonThree(); private SingletonThree () { } public static SingletonThree getSingleton() { return singleton; } } ``` > 由於例項優先提供,不存線上程安全問題,但是沒有實現懶載入。 ### 2.4 餓漢式——變種 ```java public class SingletonFour { public static SingletonFour singleton; static { singleton = new SingletonFour(); } private SingletonFour () { } public static SingletonFour getSingleton() { return singleton; } } ``` > 其實和之前的一樣,僅僅是將單例的建立挪到了靜態塊。 ### 2.5 靜態內部類式 ```java public class SingletonFive { private static class SingletonHolder { private static SingletonFive singleton = new SingletonFive(); } private SingletonFive () {} public static final SingletonFive getSingleton(){ return SingletonHolder.singleton; } } ``` > 靜態內部類保證了懶載入,單例例項優先提供又保證了執行緒安全性,較實用。 ### 2.6 列舉式 ```java public enum SingletonSix { SINGLETON; } ``` > 列舉的天然特性保證了單例,天然的私有構造器,天然的執行緒安全性,未被大規模使用的原因是枚舉出現的有點晚。 ### 2.7 雙重校驗鎖式 ```java public class SingletonSeven { private static volatile SingletonSeven singleton; private SingletonSeven() {} public static SingletonSeven getSingleton(){ if (singleton == null) { synchronized (SingletonSeven.class) { if (singleton == null) return new SingletonSeven(); } } return singleton; } } ``` > 注意: >1. volatile的使用,為了防止暴露一個未初始化的不完整單例例項; >2. 雙重判空校驗,第一個判斷避免了頻繁的加鎖,第二個判斷可以攔住多餘的建立例項的執行緒; >3. 加鎖,保證了執行緒安全(只有一個例項) 這種實現方式是經常出現在面試題中的,而且經常會要求手寫。 ## 三、總結 上面羅列的7種設計模式中第1種執行緒不安全,可以排除在外,第3、4種其實是一種,這樣下來其實可以簡化為5種方式:懶漢、餓漢、靜態內部類、列舉、雙重校驗鎖。