1. 程式人生 > >設計模式與應用:單例模式

設計模式與應用:單例模式

簡介

物件建立型模式

核心:一個類只生成唯一例項物件,構造方法私有化禁止外部建立物件。GoF對單例模式的定義是:保證一個類只有一個例項存在,同時提供能對該例項加以訪問的全域性訪問方法(靜態方法)
總結就是如下:
- 類中唯一例項引用
- 構造方法私有
- 一個靜態方法訪問該例項

為什麼使用單例模式

  • 共享資源
  • 節省物件的建立時間等等

典型單例模式

  • 餓漢式
  • 懶漢式(飽漢)(多執行緒不能保證單例模式)
  • 雙重檢查
  • 靜態內部類實現

多種實現方式

餓漢式

  • 優點:多執行緒中能夠保證單例
  • 缺點:類一載入就例項化並且一直存在,浪費資源
  • 推薦:可以使用
package
com.mym.designmodel.singleton; /** * 餓漢單例模式 */ public class ESingleton { public static ESingleton eSingleton = new ESingleton(); private ESingleton(){} public static ESingleton getSingleton(){ return eSingleton; } }

飽漢式

  • 優點:能夠懶載入
  • 缺點:多執行緒中不能保證單例
  • 推薦:不推薦使用
package com.mym.designmodel.singleton;

/**
 * 飽漢模式
 */
public class BSingleton { private static BSingleton bSingleton = null; private BSingleton(){} public static BSingleton getSingleton(){ if(bSingleton == null){ bSingleton = new BSingleton(); } return bSingleton; } }

飽漢式執行緒安全

  • 優點:能夠懶載入,保證了多執行緒中的單例
  • 缺點:阻塞模式,多執行緒執行效率較低
  • 推薦:不推薦使用
package com.mym.designmodel.singleton;

/**
 * 飽漢模式升級1
 */
public class BSingletonUp1 {

    private static BSingletonUp1 bSingletonUp1 = null;

    private BSingletonUp1(){}

    //阻塞模式
    public static synchronized  BSingletonUp1 getSingleton(){
        if(bSingletonUp1 == null){
            bSingletonUp1  = new BSingletonUp1();
        }
        return bSingletonUp1;
    }
}

雙重檢查模式單例實現

  • 優點:能夠懶載入、保證多執行緒中的單例、微阻塞
  • 缺點:第一次訪問仍然是阻塞的
  • 推薦:推薦使用,效率可以
package com.mym.designmodel.singleton;

/**
 * 雙重檢查模式
 */
public class DoubleCheckSingleton {

    private static DoubleCheckSingleton doubleCheckSingleton = null;

    private DoubleCheckSingleton(){}

    //雙重檢查 阻塞模式
    public static DoubleCheckSingleton getSingleton(){
        if(doubleCheckSingleton == null){
            synchronized (DoubleCheckSingleton.class){
                if(doubleCheckSingleton == null){
                    doubleCheckSingleton  = new DoubleCheckSingleton();
                }
            }
        }
        return doubleCheckSingleton;
    }
}

靜態內部類實現單例模式

  • 優點:懶載入、多執行緒保證單例、非阻塞、效率高
  • 缺點:較其他實現方式多了一個類資源(靜態內部類也是一個類),不過影響不大
  • 推薦:非常推薦,高效率
package com.mym.designmodel.singleton;

/**
 * 飽漢模式:靜態內部類實現,非阻塞,推薦使用
 */
public class Singleton {

    private Singleton(){}

    private static class InnerClass{
        private final static Singleton instance = new Singleton();
    }

    public static Singleton getSingleton(){
        return InnerClass.instance;
    }

}

測試

本測試著力於是否保證單例。其他執行緒安全、執行效率,筆者就不貼程式碼了

package com.mym.designmodel.singleton;

/**
 * 測試
 */
public class MainClass {

    public static void main(String[] args) {
        ESingleton eSingleton1 = ESingleton.getSingleton();
        ESingleton eSingleton2 = ESingleton.getSingleton();
        System.out.println("【ESingleton】是否為同一例項:" + (eSingleton1 == eSingleton2));

        BSingleton bSingleton1 = BSingleton.getSingleton();
        BSingleton bSingleton2 = BSingleton.getSingleton();
        System.out.println("【BSingleton】是否為同一例項:" + (bSingleton1 == bSingleton2));

        BSingletonUp1 bSingletonUp1 = BSingletonUp1.getSingleton();
        BSingletonUp1 bSingletonUp2 = BSingletonUp1.getSingleton();
        System.out.println("【BSingletonUp1】是否為同一例項:" + (bSingletonUp1 == bSingletonUp2));

        DoubleCheckSingleton doubleCheckSingleton1 = DoubleCheckSingleton.getSingleton();
        DoubleCheckSingleton doubleCheckSingleton2 = DoubleCheckSingleton.getSingleton();
        System.out.println("【DoubleCheckSingleton】是否為同一例項:" + (doubleCheckSingleton1 == doubleCheckSingleton2));

        Singleton singleton1 = Singleton.getSingleton();
        Singleton singleton2 = Singleton.getSingleton();
        System.out.println("【Singleton】是否為同一例項:" + (singleton1 == singleton2));
    }
}

輸出結果:

【ESingleton】是否為同一例項:true
【BSingleton】是否為同一例項:true
【BSingletonUp1】是否為同一例項:true
【DoubleCheckSingleton】是否為同一例項:true
【Singleton】是否為同一例項:true

單例模式的擴充套件

單例目的是節約資源。難點在於執行緒安全和效率。而單例不止是如上的實現,在java體系中,最為模範的單例模式就是列舉類,而最常用到的單例模式也還有八個基本資料型別對應的封裝類:Integer、Long、Float…檢視原始碼即可知道,他們內部都是單例且不可修改的:

Integer a = new Integer(2);
Integer b = new Integer(2);
System.out.println(a == b);

結果為false。

原始碼:Integer的內部

    /**
     * The value of the {@code Integer}.
     *
     * @serial
     */
    private final int value;

    /**
     * Constructs a newly allocated {@code Integer} object that
     * represents the specified {@code int} value.
     *
     * @param   value   the value to be represented by the
     *                  {@code Integer} object.
     */
    public Integer(int value) {
        this.value = value;
    }

由封裝類可知,實際上使用final也可以實現偽單例模式。

相關推薦

設計模式應用模式

簡介 物件建立型模式 核心:一個類只生成唯一例項物件,構造方法私有化禁止外部建立物件。GoF對單例模式的定義是:保證一個類只有一個例項存在,同時提供能對該例項加以訪問的全域性訪問方法(靜態方法) 總結就是如下: - 類中唯一例項引用 -

設計模式之三模式(餓漢式懶漢式)

//保證類在記憶體中只有一個物件 package com.xjh.demo.designpattern.pattern3; public class Student { private Student(){ } //懶漢式 priva

模式討論篇模式垃圾回收

靜態存儲區 實例化 變量 root 內存信息 本地方法棧 設計 nbsp 24* Jvm的垃圾回收機制到底會不會回收掉長時間不用的單例模式對象,這的確是一個比較有爭議性的問題。將這一部分內容單獨成篇的目的也是為了與廣大博友廣泛的討論一下這個問題。為了能讓更多的人看到這篇文章

軟體設計模式體系結構--模式

單例模式例項 餓漢模式和懶漢模式區別 一.懶漢模式 只有在自身需要的時候才會行動,從來不知道及早做好準備,它在需要物件的時候,才判斷是否已有物件,如果沒有就立即建立一個物件,然後返回,如果已有物件就不再建立,立即返回。懶漢模式只在外部物件第一次請求例項的時候才去建立。程式碼如下: 1

設計模式-建立型模式(2)

上篇我們學習了最簡單的單例模式,但在有些應用下,我們希望只有在使用到該類的時候才去建立例項,而不是在類載入的時候。 下面我們看到的單例模式實現在多執行緒併發情況下是不安全的。 public class SingletonUnSafe { private static Singlet

設計模式-建立型模式(1)

有的程式碼寫過,不再想起;有的程式碼複製粘貼後,還將回首。 上個專案已經進入收尾,利用年前的閒暇,對設計模式進行一個較為完整的學習。 這次主要參考《漫談設計模式:從面相物件開始》進行學習,程式語言將會使用java來描述。 OK, Let's go! 建立型:單例模式 如果我

設計模式應用責任鏈模式

本文介紹責任鏈模式的基本結構、應用場景、以及現有一些成熟框架的應用 簡介 Chain of Responsibility(CoR)模式也叫職責鏈模式、責任鏈模式。是行為模式之一 責任鏈模式構造一系列分別擔當不通的職責的類的

設計模式Android】模式——獨一無二的皇帝

什麼是單例模式 所謂單例模式,就是確保某一個類只有一個例項,而且自行例項化並向整個系統提供這個例項的設計模式。單例模式是最簡單的設計模式,也是應用最廣的設計模式。一般用於避免產生多個物件消耗過多的資

Cocos2d-x設計模式發掘之一模式

本系列文章我將和大家一起來發掘cocos2d-x中所使用到的設計模式,同樣的,這些模式在cocos2d-iphone中也可以找到其身影。 宣告:這裡發掘模式只是我的個人愛好,通過這個過程,我希望能加深自己對於設計模式運用的理解。關於模式的學習,市面上已經有許多非常好的書

設計模式學習總結模式(Singleton)

意圖 保證類只有一個例項,並提供一個訪問它的全域性訪問點。 適用性 當類只能有一個例項而且客戶可以通過一個眾所周知的訪問點訪問它時。 當這個唯一例項應該是通過子類可擴充套件時 結構 優缺點 優點 1>對唯一例項的受控訪

《大話設計模式》讀書筆記模式Java同步鎖synchronized

單例模式,保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。在單例模式下,類本身負責儲存它的唯一例項,這個類必須保證沒有其他例項可以被建立,並且它可以提供一個訪問該例項的方法。單例模式的類中,構造方法(函式/體)被設為private,從而堵死了外部例項化該類的可能。同

JDK設計模式模式

      單例模式用於建立那些在軟體系統中獨一無二的物件,例如資料庫管理物件,你希望在應用程式中共享該物件,完成對資料庫的統一管理以及某些軟體的引擎(如圖片渲染引擎),不同模組需要共享引擎提供的功能,而又不想建立多個引擎物件,因為引擎是一種耗資源的物件。 1、單例模式

設計模式模式的三種創建方式及其各自的優缺點

singleton dmi 創建 檢查 public pos return style tin 單例模式: 確保一個類僅僅有一個實例,並提供全局訪問點。在Java中實現單例模式須要私有的構造器,一個靜態方法和一個靜態變量。確定在性能和資源上 的限制,怎樣選擇適當的方案來

C#設計模式模式

由於 style 屬性 public readonly 靜態 don 但是 應該 在c#中的單例模式是指在一個AppDomain中只會存在一個經過實例化的對象。單例模式的作用的避免創建更多本來不用創建的對象,因為有一些對象在使用上沒有必要創建那麽多,一個就夠了。單例模式實現

C#設計模式之創建類模式模式

class style 全局 線程同步 性能 就是 線程安全 應用 過程 在程序的設計過程中很多時候系統會要求對於某個類型在一個應用程序域中只出現一次,或者是因為性能的考慮,或者是由於邏輯的要求,總之是有這樣的需求的存在,那在設計模式中正好有這麽一種模式可以來滿足這樣的要求

PHP設計模式模式

php singleton 單例模式 應用場景:在一次http請求中,多個地方使用到了數據庫連接,使用單例可以只需要創建一個連接。一個龐大的類被多次實例化的時候,會浪費巨大的內存空間。使用單例模式可以使多個對象共享內存中存在類的靜態空間。代碼示例:<?php //final防止類被

java設計模式模式

速度 [] urn == public void 支持 不變 實例化 所謂設計模式,就是一套反復會他人使用,大多數人熟知的一種設計模式。 優點: 讓代碼更容易被他人理解,保證的代碼的重用性和可靠性。 單例模式分為兩種,一種是餓漢模式,另外一種是懶漢模式。 單例模式適

《JAVA多線程編程核心技術》 筆記第六章模式多線程

會有 isp left sync con 多線程編程 鎖機制 數據 range 一、立即加載/"餓漢模式"和延遲加載/"懶漢模式" 立即加載(又稱餓漢模式):在使用類的時候已經將對象創建完畢,常見實現方法是直接new實例化 延遲加載(又稱懶漢模式):在調用get

Java設計模式(三)之建立型模式模式

一、概念: java中單例模式是一種常見的設計模式,單例模式的寫法有好幾種,這裡主要介紹三種:懶漢式單例、餓漢式單例、登記式單例。 單例模式有以下特點: (1)單例類只能有一個例項; (2)單例類必須自己建立自己的唯一例項; (3)單例類必須給所有其他物件提供這一例項。 單例

Spring中常用的設計模式模式

在Spring中,Bean可以被定義為兩種模式:prototype(原型)和singleton(單例)。 singleton(單例) 只有一個共享的例項存在,所有對這個Bean的請求都會返回這個唯一的例項。 prototype(原型) 對這個Bean的每次請求都會建立一個新