設計模式——懶漢式單例類PK餓漢式單例類
前言
我們都知道生活中好多小軟體,有的支援多IP線上,有的僅僅侷限於單個IP線上。為什麼這樣設計,在軟體開發階段就是,有需求就是發展。這就是軟體開發的一個設計模式——懶漢式單例類和餓漢式單例類。
內容
現在的網際網路發展很迅速,人們對保護自己隱私的意識也日益提高。所以單例模式就上場了,且看:
單例模式
定義:
單例模式保證一個類僅有一個例項,並提供了一個訪問它的全域性點。
解釋:
用大白話來說就是 一條路,一次只讓一個過,相當於種蘿蔔,一個坑只能種一個蘿蔔。官方講通常我們可以讓一個全域性變數使得一個物件被訪問,但它不能防止你例項化多個物件。一個最好的方法就是,讓類自身負責儲存它的唯一例項。這個類可以保證沒有其他例項可以被建立,並且可以他可以提供一個訪問該例項的方法。
看圖:
程式碼也灰常簡單哦:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//作者:周麗同
//檔案:單例模式
namespace ConsoleApplication2
{
class Singleton
{
private static Singleton instance;
private Singleton ()//構造方法讓其為private,這就堵死了外界利用new建立此類例項的可能;
{
}
public static Singleton GetInstance()//此方法時獲得本類例項的唯一全域性訪問點;
{
if (instance ==null )//若例項不存在,則new一個新的例項,否則返回已有的例項;
{
instance = new Singleton();
}
return instance;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//作者:周麗同
//檔案:單例模式
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if (s1==s2 )//比較兩次例項化後物件的結果是例項相同;
{
Console.WriteLine("兩個物件是相同的例項。");
}
Console.Read();
}
}
}
好處:
單例模式因為Singleton類封裝它的唯一例項,這樣它可以嚴格地控制客戶是怎樣訪問以及何時訪問它。就是對唯一例項的受控訪問。
完善單例——多執行緒
對於單例模式,我們只是注意到了在例項化的時候防止例項化氾濫,但是考慮細節問題,多執行緒的程式中,同時訪問Singleton類,呼叫裡面的GetInstance()方法,也會有可能造成建立多個例項的現象,給我防止這個,可以給程式加一把鎖來處理,相當於一個屋子只能進去一個人去完成任務,第一個人進去後把門鎖了,防止後面的人去屋子裡面完成在該時段的同樣的任務。
見程式碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//作者:周麗同
//檔案:多執行緒時的單例
namespace 單例模式之懶漢與餓漢
{
class Singleton
{
private static Singleton instance;
private static readonly object syncRoot = new object();
//程式執行時建立一個靜態只讀的程式輔助物件;
private Singleton ()
{
}
public static Singleton GetInstance()
{
lock (syncRoot )//在同一個時刻加了鎖的那部分程式只有一個執行緒可以進入;
{
if (instance ==null )
{
instance =new Singleton ();
}
}
return instance;
}
}
}
這裡解釋一下,Lock是確保當一個執行緒位於程式碼的臨界區時,另一個執行緒不進入臨界區。如果其他執行緒試圖進入鎖定的程式碼,則它將一直等待(即被阻止),直到該物件被釋放。由於有了 lock,就保證了多執行緒下同上訪問也不會造成多例項的生成。
多執行緒雖然解決了保證例項化一個。但是對於加鎖的方式上不管有沒有例項化物件都是先加了鎖,這樣看起來未免有點不合理。雙重鎖定解決了這種情況。
完善單例——雙重鎖定
它先是判斷例項是否存在,不存在再枷鎖處理。這樣我們不用讓執行緒每次都加鎖,而只是在例項未被建立的時候再加鎖處理,同時這樣也能保證多執行緒的安全。這就是我們所說的Double-Check Locking。至於為什麼判斷Instance是否為空兩次,第一次是判斷是否有加鎖的畢業,第二次是針對第二次以後進來的執行者是否執行例項化的判斷。
見程式碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//作者:周麗同
//檔案:雙重鎖定
namespace 雙重鎖定
{
class Singleton
{
private static Singleton instance;
private static readonly object syncRoot = new object();
private Singleton()
{
}
public static Singleton GetInstance()
{
if (instance ==null )//先判斷例項是否存在,不存在再加鎖處理;
{
lock (syncRoot )
{
//當instance不存在的情況下,當instance為 null並且同時有兩個執行緒呼叫GetInstance()方法時;
//都可以通過第一重instance==null的判斷。然後由於lock機制,這兩個執行緒則只有一個進入,另一
//個在外排隊等候。等另一個出來以後,另一個才能進入,如果沒有第二重的instance==null,還是
//可以重新建立例項的。沒有達到單例的目的。
if (instance ==null )
{
instance = new Singleton();
}
}
}
return instance;
}
}
}
靜態初始化
C#與公共語言執行庫也提供了一種“靜態初始化”方法,這種方法不需要開發人員顯式地編寫執行緒安全程式碼,即可解決多執行緒環境下它是不安全的問題。
見程式碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//作者:周麗同
//檔案:靜態初始化
namespace 靜態初始化
{
public sealed class Singleton//防止發生派生,而派生可能會增加例項;
{
//在第一次引用類的任何成員時建立例項。公共語言執行庫負責處理變數初始化;
private static readonly Singleton instance = new Singleton();
private Singleton ()
{
}
public static Singleton GetInstance()
{
return instance;
}
}
}
這個也實現了全域性訪問和例項化控制,公共靜態屬性訪問例項提供了一個全域性訪問點。不同之處在於它利用公共語言執行庫來初始化變數。構造方法和前面一樣都是私有的,不能再類本身以外例項化Singleton類;其中instance變數標記為readonly(只讀),表示只能在靜態初始化期間或在類建構函式中分配變數。
總結
靜態初始化的方式是在自己載入的時候就將自己例項化,需要提前佔用資源,所以被形象的稱之為餓漢式單例類;原先的單例模式處理方式要在第一次被引用時,才會將自己例項化,面臨著多執行緒訪問的安全性問題,需要做雙重鎖定這樣的處理才可以保證安全,所以為懶漢式單例類。本人菜鳥一枚,如果不合適的地方,望大神斧正。
1、對比著學習更加容易理解知識。
2、永遠不要相信一件東西可以近乎完美,只要發現總有更好的。
3、多做總結,多多回顧。
最後的最後,感謝您的寶貴時間~~~
相關文章
- 設計模式:單例模式 (關於餓漢式和懶漢式)設計模式單例
- C#單例—餓漢式和懶漢式C#單例
- 餓漢式單例與懶漢式單例的C#實現單例C#
- java單例模式懶漢和餓漢Java單例模式
- 【java】單例設計模式——餓漢式和懶漢式、Runtime、TimerJava單例設計模式
- 詳談單例、餓漢、和懶漢模式單例模式
- scala:分別使用懶漢式和餓漢式實現單例模式單例模式
- (單例設計模式中)懶漢式與餓漢式在多執行緒中的不同單例設計模式執行緒
- 設計模式:單例模式介紹及8種寫法(餓漢式、懶漢式、Double-Check、靜態內部類、列舉)設計模式單例
- 設計模式-單例模式之餓漢式-多執行緒設計模式單例執行緒
- 設計模式-單例模式之懶漢式-多執行緒設計模式單例執行緒
- 五種單例模式實現懶漢+餓漢+雙重檢測鎖實現+靜態內部類改進餓漢式+列舉單例模式
- java設計模式之單例模式你真的會了嗎?(懶漢式篇)Java設計模式單例
- 懶漢模式和餓漢模式模式
- java學習回顧---懶漢式和餓漢式Java
- 別再用懶漢模式了——從JVM的角度看單例模式模式JVM單例
- C++之this指標、拷貝構造、賦值構造、單列模式(餓漢模式、懶漢模式)C++指標賦值模式
- C++單例懶漢式和多執行緒問題(MUTEX 保護)C++單例執行緒Mutex
- 內部類單例模式,單例模式
- 餓漢模式C++模式C++
- 單例類單例
- 登記單式單例模式研究單例模式
- JS中的單例模式及單例模式原型類的實現JS單例模式原型
- 設計模式-單例模式設計模式單例
- [設計模式] 單例模式設計模式單例
- 設計模式 —— 單例模式設計模式單例
- 設計模式(單例模式)設計模式單例
- 設計模式——單例模式設計模式單例
- 設計模式--單例模式設計模式單例
- 設計模式 單例模式設計模式單例
- 單例設計模式單例設計模式
- DCL懶載入單例模式單例模式
- java單例類Java單例
- [設計模式]單例設計模式設計模式單例
- 設計模式-單例模式的Java程式碼體現Runtime類設計模式單例Java
- javascript類式繼承設計模式簡單介紹JavaScript繼承設計模式
- 設計模式一(單例模式)設計模式單例
- 設計模式之☞單例模式設計模式單例