1. 程式人生 > >一天一個設計模式:單例模式

一天一個設計模式:單例模式

概念:

  作為物件的建立模式,單例模式確保某一個類只有一個例項,而且自行例項化,並向整個系統提供這個例項。

特點:

  1.單例類只能有一個例項

  2.單例類必須建立自己的唯一例項

  3.單例類必須給其他所有物件提供這一例項。

餓漢式單例類

public class EagerSingleton {
    private static EagerSingleton instance = new EagerSingleton();
    /**
     * 私有預設構造子
     */
    private EagerSingleton(){}
    /**
     * 靜態工廠方法
     
*/ public static EagerSingleton getInstance(){ return instance; } }

由於選用的是靜態資源,在類載入的時候,靜態變數instance就會被初始化,類的唯一變數也在這時候建立了出來。

餓漢式,顧名思義,急於建立物件,在類載入的時候就完成了物件的建立。

餓漢式是一種採用“空間換取時間”,當類裝載的時候就會建立類的例項,不管你用不用,先建立,呼叫的時候,無需判斷直接使用,節約了時間。

懶漢式單例

public class LazySingleton {
    private static LazySingleton instance = null
; /** * 私有預設構造子 */ private LazySingleton(){} /** * 靜態工廠方法 */ public static synchronized LazySingleton getInstance(){ if(instance == null){ instance = new LazySingleton(); } return instance; } }

只有在真正需要的時候才會去建立,採用的是時間換空間,由於是執行緒安全的,會降低訪問速度。固可使用雙檢鎖的方式進行優化。

雙重檢查加鎖

機制:並不是每次進入getInstance方法都需要同步,而不是先同步,進入方法後,先檢查例項是否存在,如果不存在才進行下面的同步塊,這是第一檢查,進入同步塊後,在檢查例項是否存在,如果不存在,就在同步的情況下建立一個例項,這是第二重檢查,這樣一來就只需要同步一次,減少了多次在同步情況下進行判斷所浪費的時間。

雙檢鎖的關鍵是,使用volatile,它在此處的作用是,該變數將不會被某一個執行緒快取,而是在共享記憶體中,被所有進行讀寫的記憶體共享到,從而保證多個執行緒能夠正確處理該變數。

public class Singleton {
    private volatile static Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance(){
        //先檢查例項是否存在,如果不存在才進入下面的同步塊
        if(instance == null){
            //同步塊,執行緒安全的建立例項
            synchronized (Singleton.class) {
                //再次檢查例項是否存在,如果不存在才真正的建立例項
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

注:由於volatile關鍵字會遮蔽虛擬機器的一些程式碼優化,所以執行效率並不高,所有其實應該儘量避免使用雙檢鎖的方式來實現單例。

懶載入模式(內部類形式)

什麼是內部類:

  內部類就是指在類裡面的類,被static修飾的內部類,稱為類級內部類,無static修飾的內部類稱為物件級內部類。

  類級內部類是外部類的static部分,它的物件與外部類物件間並沒有依賴關係,因此可以直接建立。而物件級內部類的例項,是繫結在外部物件的例項中的。

  類級內部類中,可以定義靜態方法,在靜態方法中只能夠引用外部類中的靜態成員或者成員變數。

  類級內部類相當於外部類的成員,只有在第一次被使用的時候才會載入。

多執行緒預設同步鎖的相關知識:

  在下面操作下,jvm會自動為該操作進行同步,以避免出現併發安全問題。

  1.由靜態初始化器(在靜態欄位上或static{}塊中的初始化器)初始化資料。

  2.訪問final欄位時,

  3.在建立執行緒前建立物件時,

  4.執行緒可以看見它將要處理的物件時。

綜上的解決思路:

  採用靜態初始化器的方式通過jvm來保證執行緒的安全性,採用類級內部類的方式實現延遲載入。

public class Singleton {
    
    private Singleton(){}
    /**
     *    類級的內部類,也就是靜態的成員式內部類,該內部類的例項與外部類的例項
     *    沒有繫結關係,而且只有被呼叫到時才會裝載,從而實現了延遲載入。
     */
    private static class SingletonHolder{
        /**
         * 靜態初始化器,由JVM來保證執行緒安全
         */
        private static Singleton instance = new Singleton();
    }
    
    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
}

  在getInstance第一次被呼叫時,會讀取內部類的instance,這時,類級內部類完成初始化,從而建立單例,實現了延時載入,由於是靜態成員,只有在類載入的時候才載入一次,且通過jvm的預設方式實現了執行緒安全問題。

單例類列舉:

  單元素的列舉型別已經成為實現Singleton的最佳方法。用列舉來實現單例非常簡單,只需要編寫一個包含單個元素的列舉型別即可。

public enum Singleton {
    /**
     * 定義一個列舉的元素,它就代表了Singleton的一個例項。
     */
    
    uniqueInstance;
    
    /**
     * 單例可以有自己的操作
     */
    public void singletonOperation(){
        //功能處理
    }
}

  使用列舉來實現單例項控制會更加簡潔,而且無償地提供了序列化機制,並由JVM從根本上提供保障,絕對防止多次例項化,是更簡潔、高效、安全的實現單例的方式。

相關推薦

天一設計模式模式

概念:   作為物件的建立模式,單例模式確保某一個類只有一個例項,而且自行例項化,並向整個系統提供這個例項。 特點:   1.單例類只能有一個例項   2.單例類必須建立自己的唯一例項   3.單例類必須給其他所有物件提供這一例項。 餓漢式單例類 public class EagerSingleton {

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

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設計模式(三)之建立型模式模式

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

Spring中常用的設計模式模式

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

設計模式模式(餓漢)

/** * 單例模式。 * @author Bright Lee */ public class HungrySingleton { private static final HungrySingleton instance = new HungrySingleton();

設計模式模式(懶漢)

/** * 單例模式。 * @author Bright Lee */ public class LazySingleton { private static volatile LazySingleton instance; private LazySingleton() {

設計模式模式|菜鳥教程

定義 單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。 這種模式涉及到一個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。這個類提供了一種

設計模式模式程式程式碼範例

/// <summary> /// 單例模式 /// </summary> public sealed class Singleton { private static Si

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

單例模式:確保一個類只有一個例項,並提供全域性訪問點。在Java中實現單例模式需要私有的構造器,一個靜態方法和一個靜態變數。確定在效能和資源上的限制,如何選擇適當的方案來實現單例,以解決多執行緒的問題

C++ 兩種設計模式模式和觀察者監聽者模式

一、C++中有23種設計模式,大致分為建立型模式,結構型模式以及行為模式, 在這裡自己實現一下單例模式以及觀察者和監聽者模式 二、單例模式 我們通過維護一個static的成員變數來記錄唯一的物件例項,通過提供一個static的介面instance來獲得唯一的例項,就是一

JDK與設計模式模式

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

設計模式模式(Singleton)

  單例模式在23個設計模式中算得上是最簡單的一個了,也許你會有異議,那就換成“最簡單之一”,這樣就嚴謹了很多。   單例模式:保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。   適用性:當類只能有一個例項而且客戶可以從一個眾所周知的訪問點訪問它時

設計模式模式-懶漢模型和餓漢模型

什麼是單例模式? 保證一個類只有一個例項,並提供一個訪問它的全域性訪問點。首先,需要保證一個類只有一個例項;在類中,要構造一個例項,就必須呼叫類的建構函式,如此,為了防止在外部呼叫類的建構函式而構造例項,需要將建構函式的訪問許可權標記為protected或pr

python幾面試題目模式,淺拷貝與深拷貝

主要參考git上一篇面試題目,連結如下https://github.com/taizilongxu/interview_python#2-python%E4%B8%AD%E7%9A%84%E5%85%83%E7%B1%BBmetaclass 實現單例模式,對每種方式新增更詳

設計模式模式-餓漢式 懶漢式

test 一加 單例 設計模式 餓漢式 private 調用 ati 創建 懶漢模式 class Test{ //懶漢模式 類加載後不創建對象,當調用getTest時才創建對象 //延遲加載 static Test s= null; private Test(){}

設計模式模式 (關於餓漢式和懶漢式)

定義 單例模式是比較常見的一種設計模式,目的是保證一個類只能有一個例項,而且自行例項化並向整個系統提供這個例項,避免頻繁建立物件,節約記憶體。 單例模式的應用場景很多, 比如我們電腦的作業系統的回收站就是一個很好的單例模式應用,電腦上的檔案、視訊、音樂等被刪除後都會進入到回收站中;還有計算機中的印表機也是採用