您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān) Java中的單例模式是什么的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。
首先我們來看看單例模式的定義:
單例模式是 Java 中最簡單的設(shè)計模式之一,屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式。單例模式涉及到一個單一的類,該類負責(zé)創(chuàng)建自己的對象,同時確保只有單個對象被創(chuàng)建。
為了保證內(nèi)存中有且僅有一個對象,避免頻繁的創(chuàng)建對象造成對內(nèi)存的消耗,讓所有需要調(diào)用這個對象的地方都使用這一個單例對象。
接下來我們看看單例模式的類型:
1、懶漢式
懶漢式指的是在需要使用的時候才會去創(chuàng)建該單例對象。
懶漢式單例模式實現(xiàn):
public class Singleton { private static Singleton singleton; private Singleton(){ } public static Singleton getInstance(){ if (singleton == null) { singleton = new Singleton(); } return singleton; }
對于懶漢式單例實現(xiàn)存在一個問題,就是如何確保只創(chuàng)建一個對象?若兩個或多個線程同時判斷singleton為空,則會創(chuàng)建多個對象。因此我們需要解決線程安全問題。
說到線程安全想到的就是加鎖了,加鎖無非是在方法或者類對象上加鎖。
//在方法上加鎖 public class Singleton { private static Singleton singleton; private Singleton(){} public static synchronized Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } } //在類對象上加鎖 public class Singleton { private static Singleton singleton; private Singleton(){} public static Singleton getInstance() { synchronized(Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } return singleton; } }
這兩個方法,能解決多線程同時創(chuàng)建單例對象的問題,但每次獲取對象都需要先獲取鎖,并發(fā)性能差。因此還需要優(yōu)化,優(yōu)化目標為:如果沒有實例化對象,則加鎖創(chuàng)建,如果有實例化對象,則直接返回。
(學(xué)習(xí)視頻推薦:java課程)
對于在方法上加鎖,無論是否存在實例化對象都需要加鎖。故我們需要優(yōu)化的是在類對象上加鎖。
//DCL單例模式(Double Check + Lock) public class Singleton { //volatite關(guān)鍵詞防止指令重排序,下文介紹 private static volatile Singleton singleton; private Singleton(){} public static Singleton getInstance() { //如果singleton不為空,則直接返回對象,若多個線程發(fā)現(xiàn)singleton為空,則進入分支 if (singleton == null) { //多個線程同時爭搶一個鎖,只有一個線程能成功,其他線程需等待 synchronized(Singleton.class) { //爭搶到鎖的線程需再次判斷singleton是否為空,因為有可能被上個線程實例化了 //若不為空則實例化,后續(xù)線程再進入的時候則直接返回該對象 //對于之后所有進入該方法的線程則無需獲取鎖,直接返回對象 if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
上述代碼中添加了volatile關(guān)鍵詞防止指令重排序。
2、餓漢式
餓漢式指的是在類加載時即創(chuàng)建該單例對象。
餓漢式單例模式實現(xiàn):
public class Singleton { private static final Singleton singleton = new Singleton(); private Singleton(){ } public static Singleton getInstance(){ return singleton; }
總結(jié):
懶漢式:需要時才去實例化對象,在開發(fā)中如果對內(nèi)存要求很高即采用懶漢式,在多線程環(huán)境下,應(yīng)該使用DCL單例模式,使用DCL單例模式,解決了并發(fā)安全及性能低下的問題,若添加volatile關(guān)鍵詞還能防止指令重排序而發(fā)生的NPE異常。
餓漢式: 類加載時就已經(jīng)實例化對象,如果對內(nèi)存要求不高即采用餓漢式,簡單不易出錯,且沒有任何并發(fā)安全和性能問題。
感謝各位的閱讀!關(guān)于 Java中的單例模式是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。