單例模式——一個類只有一個實例

目錄

一、基礎簡介

1、定義

2、使用場景

3、優缺點

4、模式分析

二、代碼實現

1、sington類

2、代碼分析


一、基礎簡介

1、定義

保證一個類僅有一個實例,並提供一個全局訪問點

2、使用場景

  • 1、要求生產唯一序列號。
  • 2、WEB 中的計數器,不用每次刷新都在數據庫里加一次,用單例先緩存起來。
  • 3、創建的一個對象需要消耗的資源過多,比如 I/O 與數據庫的連接等。

3、優缺點

優點:

  • 1、在內存裏只有一個實例,減少了內存的開銷,尤其是頻繁的創建和銷燬實例(比如管理學院首頁頁面緩存)。
  • 2、避免對資源的多重佔用(比如寫文件操作)。

缺點:

  • 1、沒有抽象層,不能繼承擴展很難。
  •  2、違背了“單一職責原則”,一個類只重視內部關係,而忽略外部關係。
  •   3、不適用於變化對象。
  • 4、濫用單例會出現一些負面問題,如爲節省資源將數據庫連接池對象設計爲單例,可能會導致共享連接池對象對程序過多而出現連接池溢出。如果實例化的對象長時間不被利用,系統會認爲是垃圾而被回收,這樣將導致對象狀態丟失。

4、模式分析

單例模式的從實現步驟上來講,分爲三步:

  1. 構造方法私有,保證無法從外部通過 new 的方式創建對象。
  2. 對外提供獲取該類實例的靜態方法
  3. 類的內部,創建該類的對象,通過第 2 步的靜態方法返回

二、代碼實現

1、sington類

小編在此只展示完美版的單例類

package com.mfc.design.單例模式;

/**
 * @author MouFangCai
 * @date 2019/10/21 16:48
 *
 * @description
 */
public class Singleton {

    // 靜態內部類
    // 由於SingletonInstance是私有靜態內部類,所以不會被其他類知道
    private static class SingletonInstance{
        // 由於這個instance是static的,因此並不會構造多次
        // 類的構造必須是原子性的,非併發的,因此不需要加同步塊
        private static final Singleton instance = new Singleton();
    }
    // 構造私有化,防止外部通過 new 的方式創建對象
    private Singleton() {

    }

    // 對外提供 獲取實例 的靜態方法
    public static Singleton getInstance(){
        return SingletonInstance.instance;
    }
}

2、代碼分析

在上面的單例模式實現代碼中,我們使用了Java的靜態內部類。這一技術是被JVM明確說明了的,因此不存在任何二義性。在這段代碼中,因爲Singleton沒有static的屬性,因此並不會被初始化。直到調用getInstance()的時候,會首先加載SingletonInstance類,這個類有一個static的SingletonClass實例,因此需要調用Singleton的構造方法,然後getInstance()將把這個內部類的instance返回給使用者。由於這個instance是static的,因此並不會構造多次。

由於SingletonInstance是私有靜態內部類,所以不會被其他類知道,同樣,static語義也要求不會有多個實例存在。並且,JSL規範定義,類的構造必須是原子性的,非併發的,因此不需要加同步塊。同樣,由於這個構造是非併發的,所以getInstance()也並不需要加同步

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章