成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java 設(shè)計(jì)模式 單例模式

wall2flower / 457人閱讀

摘要:單例類如果一個(gè)類始終只能創(chuàng)建一個(gè)實(shí)例,則這個(gè)類被稱為單例類在一些特殊場景下,要求不允許自由創(chuàng)建該類的對象,而只允許為該類創(chuàng)建一個(gè)對象。

單例(Singleton)類

如果一個(gè)類始終只能創(chuàng)建一個(gè)實(shí)例,則這個(gè)類被稱為單例類

在一些特殊場景下,要求不允許自由創(chuàng)建該類的對象,而只允許為該類創(chuàng)建一個(gè)對象。為了避免其他類自由創(chuàng)建該類的實(shí)例,應(yīng)該把該類的構(gòu)造器使用private修飾,從而把該類的所有構(gòu)造器隱藏起來

根據(jù)良好封裝的原則:一旦把該類的構(gòu)造器隱藏起來,就需要一個(gè)public方法作為該類的訪問點(diǎn),用于創(chuàng)建該類的對象,且該方法必須使用static修飾(因?yàn)檎{(diào)用該方法之前還不存在對象,因此調(diào)用該方法的不可能是對象,只能是類)

除此之外,該類還必須緩存已經(jīng)創(chuàng)建的對象,否則該類無法知道是否曾經(jīng)創(chuàng)建過對象,也就無法保證只創(chuàng)建了一個(gè)對象。為此該類需要使用一個(gè)成員變量來保存曾經(jīng)創(chuàng)建的對象,因?yàn)樵摮蓡T變量需要被上面的靜態(tài)方法訪問,故該成員變量必須使用static修飾

class Singleton
{
    // 使用一個(gè)類變量來緩存曾經(jīng)創(chuàng)建的實(shí)例
    private static Singleton instance;
    // 將構(gòu)造器使用private修飾,隱藏該構(gòu)造器
    private Singleton(){}
    // 提供一個(gè)靜態(tài)方法,用于返回Singleton實(shí)例
    // 該方法可以加入自定義的控制,保證只產(chǎn)生一個(gè)Singleton對象
    public static Singleton getInstance()
    {
        // 如果instance為null,表明還不曾創(chuàng)建Singleton對象
        // 如果instance不為null,則表明已經(jīng)創(chuàng)建了Singleton對象,
        // 將不會(huì)重新創(chuàng)建新的實(shí)例
        if (instance == null)
        {
            // 創(chuàng)建一個(gè)Singleton對象,并將其緩存起來
            instance = new Singleton();
        }
        return instance;
    }
}
public class SingletonTest
{
    public static void main(String[] args)
    {
        // 創(chuàng)建Singleton對象不能通過構(gòu)造器,
        // 只能通過getInstance方法來得到實(shí)例
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        System.out.println(s1 == s2); // 將輸出true
    }
}
Coding

代碼一:

public class Singleton {  
    private Singleton() {}                     // 關(guān)鍵點(diǎn)0:構(gòu)造函數(shù)是私有的
    private static Singleton single = null;    // 關(guān)鍵點(diǎn)1:聲明單例對象是靜態(tài)的
    public static Singleton GetInstance()      // 通過靜態(tài)方法來構(gòu)造對象
    {                        
         if (single == null)
         {                                     // 關(guān)鍵點(diǎn)2:判斷單例對象是否已經(jīng)被構(gòu)造
             single = new Singleton();  
         }    
        return single;  
    }  
}

代碼一是線程不安全的,遇到多線程的并發(fā)條件下,有可能給new出多個(gè)單例實(shí)例

========================================================================================

代碼二:

public class Singleton {  
    private Singleton() {}                     // 關(guān)鍵點(diǎn)0:構(gòu)造函數(shù)是私有的
    private static Singleton single = null;    // 關(guān)鍵點(diǎn)1:聲明單例對象是靜態(tài)的
    private static Object obj= new Object();
    public static Singleton GetInstance()      // 通過靜態(tài)方法來構(gòu)造對象
    {                        
         if (single == null)                   // 關(guān)鍵點(diǎn)2:判斷單例對象是否已經(jīng)被構(gòu)造
         {                            
            lock(obj)                          // 關(guān)鍵點(diǎn)3:加線程鎖
            {
               single = new Singleton();  
             }
         }    
        return single;  
    }  
}

在關(guān)鍵點(diǎn)2,檢測單例是否被構(gòu)造。雖然這里判斷了一次,但是由于某些情況下,可能有延遲加載或者緩存的原因,只有關(guān)鍵點(diǎn)2這一次判斷,仍然不能保證系統(tǒng)是否只創(chuàng)建了一個(gè)單例,也可能出現(xiàn)多個(gè)實(shí)例的情況

========================================================================================

代碼三:

public class Singleton {  
    private Singleton() {}                     // 關(guān)鍵點(diǎn)0:構(gòu)造函數(shù)是私有的
    private static Singleton single = null;    // 關(guān)鍵點(diǎn)1:聲明單例對象是靜態(tài)的
    private static object obj= new object();
    public static Singleton GetInstance()      // 通過靜態(tài)方法來構(gòu)造對象
    {                        
         if (single == null)                   // 關(guān)鍵點(diǎn)2:判斷單例對象是否已經(jīng)被構(gòu)造
         {                            
            lock(obj)                          // 關(guān)鍵點(diǎn)3:加線程鎖
            {
               if(single == null)              // 關(guān)鍵點(diǎn)4:二次判斷單例是否已經(jīng)被構(gòu)造
               {
                  single = new Singleton();  
                }
             }
         }    
        return single;  
    }  
}

在判斷單例實(shí)例是否被構(gòu)造時(shí),需要檢測兩次,在線程鎖之前判斷一次,在線程鎖之后判斷一次,再去構(gòu)造實(shí)例

單例模式關(guān)鍵點(diǎn)

單例是為了保證系統(tǒng)中只有一個(gè)實(shí)例,其關(guān)鍵點(diǎn)有:

私有構(gòu)造函數(shù)

聲明靜態(tài)單例對象

構(gòu)造單例對象之前要加鎖(lock一個(gè)靜態(tài)的object對象)

需要兩次檢測單例實(shí)例是否已經(jīng)被構(gòu)造,分別在鎖之前和鎖之后

單例模式問答 為何要檢測兩次?

如上面所述,有可能延遲加載或者緩存原因,造成構(gòu)造多個(gè)實(shí)例,違反了單例的初衷

構(gòu)造函數(shù)能否公有化?

不行,單例類的構(gòu)造函數(shù)必須私有化,單例類不能被實(shí)例化,單例實(shí)例只能靜態(tài)調(diào)用

lock住的對象為什么要是object對象,可以是int嗎?

不行,鎖住的必須是個(gè)引用類型。如果鎖值類型,每個(gè)不同的線程在聲明的時(shí)候值類型變量的地址都不一樣,那么上個(gè)線程鎖住的東西下個(gè)線程進(jìn)來會(huì)認(rèn)為根本沒鎖,相當(dāng)于每次都鎖了不同的門。引用類型的變量地址是相同的,每個(gè)線程進(jìn)來判斷鎖都想是否被鎖的時(shí)候都是判斷同一個(gè)地址,相當(dāng)于是鎖在通一扇門,起到了鎖的作用

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/66498.html

相關(guān)文章

  • 單例模式你會(huì)幾種寫法?

    摘要:使用靜態(tài)類體現(xiàn)的是基于對象,而使用單例設(shè)計(jì)模式體現(xiàn)的是面向?qū)ο?。二編寫單例模式的代碼編寫單例模式的代碼其實(shí)很簡單,就分了三步將構(gòu)造函數(shù)私有化在類的內(nèi)部創(chuàng)建實(shí)例提供獲取唯一實(shí)例的方法餓漢式根據(jù)上面的步驟,我們就可以輕松完成創(chuàng)建單例對象了。 前言 只有光頭才能變強(qiáng) 回顧前面: 給女朋友講解什么是代理模式 包裝模式就是這么簡單啦 本來打算沒那么快更新的,這陣子在刷Spring的書籍。在看...

    solocoder 評論0 收藏0
  • 設(shè)計(jì)模式單例模式

    摘要:單例模式關(guān)注的重點(diǎn)私有構(gòu)造器線程安全延遲加載序列化和反序列化安全反射攻擊安全相關(guān)設(shè)計(jì)模式單例模式和工廠模式工廠類可以設(shè)計(jì)成單例模式。 0x01.定義與類型 定義:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn) 類型:創(chuàng)建型 UML showImg(https://segmentfault.com/img/bVbtDJ2?w=402&h=268); 單例模式的基本要素 私有的構(gòu)造方...

    陸斌 評論0 收藏0
  • Java設(shè)計(jì)模式-單例模式(Singleton Pattern)

    摘要:如果需要防范這種攻擊,請修改構(gòu)造函數(shù),使其在被要求創(chuàng)建第二個(gè)實(shí)例時(shí)拋出異常。單例模式與單一職責(zé)原則有沖突。源碼地址參考文獻(xiàn)設(shè)計(jì)模式之禪 定義 單例模式是一個(gè)比較簡單的模式,其定義如下: 保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。 或者 Ensure a class has only one instance, and provide a global point of ac...

    k00baa 評論0 收藏0
  • 深入理解單例模式

    摘要:總結(jié)我們主要介紹到了以下幾種方式實(shí)現(xiàn)單例模式餓漢方式線程安全懶漢式非線程安全和關(guān)鍵字線程安全版本懶漢式雙重檢查加鎖版本枚舉方式參考設(shè)計(jì)模式中文版第二版設(shè)計(jì)模式深入理解單例模式我是一個(gè)以架構(gòu)師為年之內(nèi)目標(biāo)的小小白。 初遇設(shè)計(jì)模式在上個(gè)寒假,當(dāng)時(shí)把每個(gè)設(shè)計(jì)模式過了一遍,對設(shè)計(jì)模式有了一個(gè)最初級的了解。這個(gè)學(xué)期借了幾本設(shè)計(jì)模式的書籍看,聽了老師的設(shè)計(jì)模式課,對設(shè)計(jì)模式算是有個(gè)更進(jìn)一步的認(rèn)識。...

    FuisonDesign 評論0 收藏0
  • Java基礎(chǔ)學(xué)習(xí)——多線程之單例設(shè)計(jì)模式(轉(zhuǎn))

    摘要:總之,選擇單例模式就是為了避免不一致狀態(tài),避免政出多頭。二餓漢式單例餓漢式單例類在類初始化時(shí),已經(jīng)自行實(shí)例化靜態(tài)工廠方法餓漢式在類創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對象供系統(tǒng)使用,以后不再改變,所以天生是線程安全的。 概念:  Java中單例模式是一種常見的設(shè)計(jì)模式,單例模式的寫法有好幾種,這里主要介紹兩種:懶漢式單例、餓漢式單例?! 卫J接幸韵绿攸c(diǎn):  1、單例類只能有一個(gè)實(shí)例?!?..

    dendoink 評論0 收藏0
  • 從未這么明白的設(shè)計(jì)模式(一):單例模式

    摘要:一般來說,這種單例實(shí)現(xiàn)有兩種思路,私有構(gòu)造器,枚舉。而這種方式又分了飽漢式,餓漢式。通過關(guān)鍵字防止指令重排序。什么是單例?為什么要用單例? 一個(gè)類被設(shè)計(jì)出來,就代表它表示具有某種行為(方法),屬性(成員變量),而一般情況下,當(dāng)我們想使用這個(gè)類時(shí),會(huì)使用new關(guān)鍵字,這時(shí)候jvm會(huì)幫我們構(gòu)造一個(gè)該類的實(shí)例。而我們知道,對于new這個(gè)關(guān)鍵字以及該實(shí)例,相對而言是比較耗費(fèi)資源的。所以如果我們能夠想...

    NikoManiac 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<