1. 程式人生 > >單例模式的優缺點

單例模式的優缺點

單例模式(Singleton Pattern):確保某一個類只有一個例項,而且自行例項化並向整個系統提供這個例項,這個類稱為單例類,它提供全域性訪問的方法。單例模式是一種物件建立型模式。

單例模式有三個要點:一是某個類只能有一個例項;二是它必須自行建立這個例項;三是它必須自行向整個系統提供這個例項。
單例模式是結構最簡單的設計模式一,在它的核心結構中只包含一個被稱為單例類的特殊類。
這裡寫圖片描述

單例模式結構圖中只包含一個單例角色:
Singleton(單例):在單例類的內部實現只生成一個例項,同時它提供一個靜態的getInstance()工廠方法,讓客戶可以訪問它的唯一例項;為了防止在外部對其例項化,將其建構函式設計為私有;在單例類內部定義了一個Singleton型別的靜態物件,作為外部共享的唯一例項。
主要優點:

  • 1、提供了對唯一例項的受控訪問。
  • 2、由於在系統記憶體中只存在一個物件,因此可以節約系統資源,對於一些需要頻繁建立和銷燬的物件單例模式無疑可以提高系統的效能。
  • 3、允許可變數目的例項。

主要缺點:

  • 1、由於單利模式中沒有抽象層,因此單例類的擴充套件有很大的困難。
  • 2、單例類的職責過重,在一定程度上違背了“單一職責原則”。
  • 3、濫用單例將帶來一些負面問題,如為了節省資源將資料庫連線池物件設計為的單例類,可能會導致共享連線池物件的程式過多而出現連線池溢位;如果例項化的物件長時間不被利用,系統會認為是垃圾而被回收,這將導致物件狀態的丟失。

適用場景
在以下情況下可以考慮使用單例模式:
- (1) 系統只需要一個例項物件,如系統要求提供一個唯一的序列號生成器或資源管理器,或者需要考慮資源消耗太大而只允許建立一個物件。
- (2) 客戶呼叫類的單個例項只允許使用一個公共訪問點,除了該公共訪問點,不能通過其他途徑訪問該例項。

餓漢式單例類與懶漢式單例類比較
餓漢式單例類在類被載入時就將自己例項化,它的優點在於無須考慮多執行緒訪問問題,可以確保例項的唯一性;從呼叫速度和反應時間角度來講,由於單例物件一開始就得以建立,因此要優於懶漢式單例。但是無論系統在執行時是否需要使用該單例物件,由於在類載入時該物件就需要建立,因此從資源利用效率角度來講,餓漢式單例不及懶漢式單例,而且在系統載入時由於需要建立餓漢式單例物件,載入時間可能會比較長。
懶漢式單例類在第一次使用時建立,無須一直佔用系統資源,實現了延遲載入,但是必須處理好多個執行緒同時訪問的問題,特別是當單例類作為資源控制器,在例項化時必然涉及資源初始化,而資源初始化很有可能耗費大量時間,這意味著出現多執行緒同時首次引用此類的機率變得較大,需要通過雙重檢查鎖定等機制進行控制,這將導致系統性能受到一定影響。

一種更好的單例實現方法
餓漢式單例類不能實現延遲載入,不管將來用不用始終佔據記憶體;懶漢式單例類執行緒安全控制煩瑣,而且效能受影響。可見,無論是餓漢式單例還是懶漢式單例都存在這樣那樣的問題,有沒有一種方法,能夠將兩種單例的缺點都克服,而將兩者的優點合二為一呢?答案是:Yes!下面我們來學習這種更好的被稱之為Initialization on Demand Holder (IoDH)的技術。
在IoDH中,我們在單例類中增加一個靜態(static)內部類,在該內部類中建立單例物件,再將該單例物件通過getInstance()方法返回給外部使用,實現程式碼如下所示:

//Initialization on Demand Holder
public class Singleton
{
       private  Singleton()
{
       }

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

       public static Singleton getInstance()
       {
              return HolderClass.instance;
       }

       public  static void main(String args[])
       {
              Singleton  s1, s2;
s1 = Singleton.getInstance();
              s2  = Singleton.getInstance();
              System.out.println(s1==s2);
       }
}

編譯並執行上述程式碼,執行結果為:true,即建立的單例物件s1和s2為同一物件。由於靜態單例物件沒有作為Singleton的成員變數直接例項化,因此類載入時不會例項化Singleton,第一次呼叫getInstance()時將載入內部類HolderClass,在該內部類中定義了一個static型別的變數instance,此時會首先初始化這個成員變數,由Java虛擬機器來保證其執行緒安全性,確保該成員變數只能初始化一次。由於getInstance()方法沒有任何執行緒鎖定,因此其效能不會造成任何影響。
通過使用IoDH,我們既可以實現延遲載入,又可以保證執行緒安全,不影響系統性能,不失為一種最好的Java語言單例模式實現方式(其缺點是與程式語言本身的特性相關,很多面向物件語言不支援IoDH)。

相關推薦

模式優缺點

主要優點: 1、提供了對唯一例項的受控訪問。 2、由於在系統記憶體中只存在一個物件,因此可以節約系統資源,對於一些需要頻繁建立和銷燬的物件單例模式無疑可以提高系統的效能。 3、允許可變數目的例項。 主要缺點: 1、由於單利模式中沒有抽象層,因此單例類的擴充套件有很大的困難

java模式優缺點(懶漢模式,餓漢模式,雙重檢查加鎖模式

三種單例模式實際都是有運用的。 優點:延遲載入 缺點:不加同步的懶漢式是執行緒不安全的,加了synchronized之後就變成執行緒安全的了 public class Singleton { private static Singleton singleto

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

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

模式的三種實現 以及各自的優缺點

屏蔽 () 模式 避免 sync code 實例化 pan single 單例模式:單例模式的意思就是只有一個實例。單例模式確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例。這個類稱為單例類。 單例模式有三種:懶漢式單例,餓漢式單例,登記式單例。 1.

模式的三種寫法和優缺點

兩種 system 一個 obj cti sin clr 效果 returns 1 using System; 2 using System.Collections.Generic; 3 4 namespace ConsoleApp1 5 { 6 c

java模式雙重檢驗鎖的優缺點?還有哪些實現方式?列舉一些使用場景

2018年7月18日,在專案程式碼中看到單例模式,總結一下單例模式的知識點. 單例模式的概念: 在應用程式的生命週期中,在任意時刻,引用某個類的例項都是同一個.在一個系統中有些類只需要有一個全域性物件,統一管理系統行為和執行某些操作.例如在使用hibernate時,ses

三維分析Java模式各實現方式的優缺點

一、餓漢式(Eager Singleton) package main.singleton; /** * Created by leboop on 2018/11/27. * 宣告為final,不可被繼承 */ public final class EagerSingleton {

Java中四種常見的模式以及各自優缺點總結

餓漢式實現:餓漢式單例模式程式碼中,static變數會在類裝載時初始化,此時也不會涉及多個執行緒物件訪問該物件的問題。虛擬機器保證只會裝載一次該類,肯定不會發生併發訪問的問題。因此,可以省略synchronized關鍵字。問題:如果只是載入本類,而不是呼叫getInstan

java設計模式模式5種方法及優缺點小結

單例設計模式的用處。 單例設計模式是指,某個類只有一個例項。在計算機系統中類似於印表機和最常見的就是工作管理員的對話方塊,不管幾個使用者同時登入windows 開啟的任務對話方塊只有一個。 常見的幾種實現方式: 1.lazy-load /*

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

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

模式優缺點

單例模式(Singleton Pattern):確保某一個類只有一個例項,而且自行例項化並向整個系統提供這個例項,這個類稱為單例類,它提供全域性訪問的方法。單例模式是一種物件建立型模式。 單例模式有三個要點:一是某個類只能有一個例項;二是它必須自行建立這個例項

android中模式優缺點

    本篇文章主要介紹android開發中常用的單例模式和其中的幾種寫法,分析介紹在安卓開發中單例模式的優缺點。一、常見的幾種單例模式    首先來回顧一下幾種常見的單例模式,分析一下個自的優缺點    1.懶漢式    //懶漢式單例類.在第一次呼叫的時候例項化自己   

java設計模式之五 —— 模式的三種模式優缺點整理

本來一直以為單例很簡單,不打算整理了。不過本著求學需嚴謹的心態,還是去看了一下。確實有所收穫。 單例模式:單例模式的意思就是隻有一個例項。單例模式確保某一個類只有一個例項,而且自行例項化並向整個系統提供這個例項。這個類稱為單例類。 單例模式有三種:懶漢式單例

模式優缺點和使用場景

文章轉自:http://www.tools138.com/create/article/20150929/020009847.html 單利模式的優缺點和使用場景  首先介紹一下單例模式:      單例模式(Singleton),也叫單子模式,是一種常用的軟體設計模式。在應用這個模式時,單例物件的類必須保

設計模式之——模式(Singleton)的實現、優缺點和常見應用場景

單例模式(Singleton)也叫單態模式,是設計模式中最為簡單的一種模式,甚至有些模式大師都不稱其為模式,稱其為一種實現技巧,因為設計模式講究物件之間的關係的抽象,而單例模式只有自己一個物件,也因此有些設計大師並把把其稱為設計模式之一。 好多沒怎麼使用過的人可能會想,單例模式感覺不怎麼用到,實際的應

模式的五種實現方式及優缺點

> **公號:碼農充電站pro** > **主頁:** 當我們需要使得某個類只能有一個例項時,可以使用**單例模式**。 **單例模式**(*Singleton Design Pattern*)保證一個類只能有一個例項,並提供一個全域性訪問點。 單例模式的實現需要**三個必要的條件**: 1. 單例類

模式

實現 程序 先來 null effective 如果 ava 不同的 aps 單例模式:確保某一個類只有一個實例,而且自行實例化並向整個系統提供這個實例。 優點: 1、省略創建對象所花費的時間減少系統開銷,尤其是重量級對象。 2、減少對象的創建,減輕GC壓力。 3、設置全局

GOF23—模式(2)

應該 一個 img bsp 漏洞 資源 nbsp 創建 就會 本文介紹單例模式(不包含枚舉單例模式)漏洞問題以及如何防止漏洞   1.反射可以破解單例模式,例子如下:       此時,我們運行Client類,發現s1和s2是一個對象,但s3和s4是不同的對象。 那麽如何防

溫故而知新(java實現)模式的七種寫法

反序 防止 代碼 工作 html 我想 變種 evel 才會 第一種(懶漢,線程不安全): Java代碼 public class Singleton { private static Singleton instance; private S

模式和線程安全

tac 可能 存在 版本 線程不安全 廣東 多線程 一個 單例 前幾天給項目的省市區加了redis。結果上線沒多久就發生了數據錯亂的現象,需要讀取山東省的市可能返回的市廣東的。一開始不明白哪裏有問題,因為測試組的同學有測試過,在測試過程種並沒有發生這樣的情況。由於使用了se