詳解java中的6種單例寫法及優(yōu)缺點
在java中,單例有很多種寫法,面試時,手寫代碼環(huán)節(jié),除了寫算法題,有時候也會讓手寫單例模式,這里記錄一下單例的幾種寫法和優(yōu)缺點。
1.初級寫法
2.加鎖
3.餓漢式
4.懶漢式
5.雙鎖檢驗
6.內(nèi)部類
1.初級寫法
package com.java4all.test6; /** * Author: yunqing * Date: 2018/8/13 * Description:單例模式 -- 初級 */ public class Singleton { private static Singleton singleton = null; public Singleton() { } /**并發(fā)下會產(chǎn)生多個實例*/ public static Singleton getInstance(){ if(singleton == null){ singleton = new Singleton(); } return singleton; } }
上面這種寫法,在并發(fā)環(huán)境下,會出現(xiàn)多個實例。
2.加鎖
我們優(yōu)化上面的代碼,遇到并發(fā),很容易想到加鎖,把獲取對象的方法加上關(guān)鍵字synchronized,很巧,這種寫法也稱為懶漢式單例 ,如下:
package com.java4all.test6; /** * Author: yunqing * Date: 2018/8/13 * Description: */ public class BadSynchronizedSingleton { private static BadSynchronizedSingleton synchronizedSingleton; private BadSynchronizedSingleton() { } /** * 缺點:等待時間長 * 這種整個方法都同步了,效率很低 * */ public synchronized static BadSynchronizedSingleton getInstance(){ if(synchronizedSingleton == null){ synchronizedSingleton = new BadSynchronizedSingleton(); } return synchronizedSingleton; } }
但是,顯然,我們把整個方法都同步了,效率很低下,我們可以繼續(xù)優(yōu)化,只在創(chuàng)建實例的地方加上同步,參考5雙鎖檢驗。
3.餓漢式
餓漢式的特點是:類在加載時就直接初始化了實例。即使沒用到,也會實例化。
package com.java4all.test6; /** * Author: yunqing * Date: 2018/8/13 * Description:餓漢式單例模式--類初始化時就自行實例化 */ public class ESingleton { /**類在加載的時候直接進(jìn)行初始化*/ private static final ESingleton ESINGLETON = new ESingleton(); private ESingleton() {} /**對外暴露唯一接口 提供單例對象*/ public static ESingleton geteSingleton(){ return ESINGLETON; } }
4.懶漢式
懶漢式的特點是:用到這個實例時才去調(diào)用方法實例化。這個和2中的看起來是一樣的,因為這個實例化方法加了synchronized ,這樣安全一些。
package com.java4all.test6; /** * Author: yunqing * Date: 2018/8/13 * Description:懶漢式單例模式 * 第一次調(diào)用時實例化 */ public class BSingleton { private static BSingleton bSingleton ; private BSingleton() { } /** * 整個方法鎖住了,效率較低 * @return */ public synchronized static BSingleton getbSingleton(){ if(bSingleton == null){ bSingleton = new BSingleton(); } return bSingleton; } }
5.雙鎖檢驗
雙重非空判斷,new對象前加一次鎖。
volatile關(guān)鍵字,考慮的是,new關(guān)鍵字在虛擬機(jī)中執(zhí)行時其實分為很多步驟,具體原因可以參考深入理解java虛擬機(jī)一書(考慮的是這個new關(guān)鍵字字節(jié)碼執(zhí)行時是非原子性的),而volatile關(guān)鍵字可以防止指令重排。
package com.java4all.test6; /** * Author: yunqing * Date: 2018/8/13 * Description:雙鎖檢驗 */ public class SynchronizedSingleton { /**volatile防止指令重排*/ private static volatile SynchronizedSingleton singleton; private SynchronizedSingleton() { } /**只是在實例為空時才進(jìn)行同步創(chuàng)建 * 為什么做了2次判斷? * A線程和B線程同時進(jìn)入同步方法0 * 然后都在1位置處判斷了實例為null * 然后都進(jìn)入了同步塊2中 * 然后A線程優(yōu)先進(jìn)入了同步代碼塊2中(B線程也進(jìn)入了),然后創(chuàng)建了實例 * 此時,如果沒有3處的判斷,那么A線程創(chuàng)建實例同時,B線程也會創(chuàng)建一個實例 * 所以,還需要做2次判斷 * */ public static SynchronizedSingleton getInstance(){//0 if(singleton == null){//1 synchronized (SynchronizedSingleton.class){//2 if(singleton == null){//3 singleton = new SynchronizedSingleton();//4 } } } return singleton; } }
6.內(nèi)部類
package com.java4all.test6; /** * Author: yunqing * Date: 2018/9/15 * Description:靜態(tài)內(nèi)部類 * 優(yōu)點:1.延遲,外部類初始化時不會進(jìn)行實例創(chuàng)建,要用時才會創(chuàng)建 * 2.安全,靜態(tài)成員變量 */ public class FSingleton { private FSingleton() { } public static FSingleton getInstance(){ return Singleton.fSingleton; } private static class Singleton{ private static FSingleton fSingleton = new FSingleton(); } }
總結(jié)
以上所述是小編給大家介紹的java中的6種單例寫法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
SpringMVC+Mybatis二維碼實現(xiàn)多平臺付款(附源碼)
本文主要實現(xiàn)微信支付寶等支付平臺合多為一的二維碼支付,并且實現(xiàn)有效時間內(nèi)支付有效,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08Java switch case數(shù)據(jù)類型原理解析
這篇文章主要介紹了Java switch case數(shù)據(jù)類型原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-01-01Java實現(xiàn)文件監(jiān)控器FileMonitor的實例代碼
這篇文章主要介紹了Java實現(xiàn)文件監(jiān)控器FileMonitor的實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-12-12Windows中使用Java生成Excel文件并插入圖片的方法
這篇文章主要介紹了Windows中使用Java生成Excel文件并插入圖片的方法,其中向Excel中插入圖片文中通過使用Apache POI來實現(xiàn),需要的朋友可以參考下2016-02-02Spring?Boot項目集成Knife4j接口文檔的實例代碼
Knife4j就相當(dāng)于是swagger的升級版,對于我來說,它比swagger要好用得多<BR>,這篇文章主要介紹了Spring?Boot項目集成Knife4j接口文檔的示例代碼,需要的朋友可以參考下2021-12-12文件路徑正確,報java.io.FileNotFoundException異常的原因及解決辦法
這篇文章主要介紹了文件路徑正確,報java.io.FileNotFoundException異常的原因及解決辦法的相關(guān)資料,需要的朋友可以參考下2016-04-04Idea+maven搭建SSH(struts2+hibernate5+spring5)環(huán)境的方法步驟
這篇文章主要介紹了Idea+maven搭建SSH(struts2+hibernate5+spring5)環(huán)境的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06