1. 程式人生 > >單例模式(餓漢模式和懶漢模式)

單例模式(餓漢模式和懶漢模式)

單例模式也叫單件模式。Singleton是一個非常常用的設計模式,幾乎所有稍微大一些的程式都會使用到它,所以構建一個執行緒安全並且高效的Singleton很重要。
單例模式的特點:
1>單例類保證全域性只有一個唯一例項物件。
2>單例類提供獲取這個唯一例項的介面。

1.下面先簡單設計一個單例模式
這裡寫圖片描述
這裡寫圖片描述
但是這樣設計會有執行緒安全的問題。為什麼說這樣實現的一個單例模式是執行緒不安全的呢?是因為暴露給外部介面的函式中_inst=new Singleton;是非原子操作,易出現執行緒安全問題。
2. 針對執行緒安全有以下解決方法:
(一)加鎖
(二)使非原子操作變為原子的,一般系統會提供一個原子性操作函式(給CPU做一個標記,告訴CPU只要該操作開始執行就不能被切換出去)
下面主要以第一種方式來解決問題!
在Linux下POSIX機制中有lock,unlock等,但在Windows下一般不提供鎖機制,使用臨界區的形式,但是在C++11庫中提供了鎖機制。
先引入標頭檔案:#include
定義鎖變數:
這裡寫圖片描述


在類外進行初始化:
這裡寫圖片描述
給執行緒不安全的地方加鎖:
這裡寫圖片描述
但是加鎖後引來一個性能問題,單例模式的設計我們講究高效,所以在這基礎上還應該優化,可以採取雙重檢查的方式。
這裡寫圖片描述
上面加鎖後又會引發死鎖情況,如果在_inst=new Singleton;這裡分配空間失敗,可能會丟擲異常,這時去捕獲異常的話就會引發死鎖的情況,針對這種情況我們可以用RAII機制去解決,類似於智慧指標。
這裡寫圖片描述
這裡寫圖片描述
寫好的程式碼經過編譯後為可執行的二進位制檔案給CPU去執行,CPU可能會優化一些指令,比如:_inst=new Singleton;分為三步去執行:一是分配空間,二是調建構函式,三是賦值。加入雙重檢查可能會帶來的一個問題是CPU對指令優化從而打亂執行順序導致錯誤,如果二三步驟顛倒,沒有調建構函式前可能為一個隨機數或野指標,如果這時賦值,然後這時該執行緒被切出去,再來一個執行緒檢查它不為0或NULL就直接返回該值導致一些意想不到的問題。我們可以呼叫windows系統下的函式MemoryBarrier(); //記憶體柵欄函式來保證下面的tmp是一個完整的物件指標。
這裡寫圖片描述

該種就是最終版的懶漢單例模式(執行緒安全的且高效).

3.下面再介紹兩種餓漢單例模式:
(1)利用靜態成員變數初始化在調main函式之前的特性實現,這種方式沒有加鎖,沒有雙重檢查,也不用考慮異常捕獲造成的記憶體洩漏。
這裡寫圖片描述
這裡寫圖片描述
(2)在呼叫介面函式獲得物件時才臨時建立
這裡寫圖片描述

4.餓漢模式用於靜態聯編沒有問題,但是在動態聯編會出現問題。
靜態編譯是將連結庫都載入到該目的碼中,但是動態編譯是執行起來才將連結檔案載入進來,這會兒用餓漢模式可能物件的初始化會存在問題。

相關推薦

JAVA設計模式懶漢式的區別

定義:確保一個類只有一個例項,而且自行例項化並向整個系統提供這個例項。 型別:建立類模式 類圖: 類圖知識點: 1.類圖分為三部分,依次是類名、屬性、方法 2.以<<開頭和以>>結尾的為註釋資訊 3.修飾符+代表public,-代表p

模式的實現懶漢式

null cte get pri single singleton ins 安全 tin 1.懶漢模式。 class Singleton { private: static Singleton* m_instance; Singleton(

Java—設計模式懶漢設計模式

1.單例模式 定義:一個類只允許產生一個例項化物件。 a.物件如何產生? 通過類的構造方法 b.要想限制物件的產生? 通過構造方法限制,構造方法私有化,類外部無法產生例項化物件。 餓漢式單例:上來就new //餓漢式單例 class Singleton{

模式模式懶漢模式

單例模式也叫單件模式。Singleton是一個非常常用的設計模式,幾乎所有稍微大一些的程式都會使用到它,所以構建一個執行緒安全並且高效的Singleton很重要。 單例模式的特點: 1>單例類保證全域性只有一個唯一例項物件。 2>單例類提供獲取

java學習之模式式與懶漢式

分用 單例設計 單例 null 並發 auth 設計 pack 過多 ---恢復內容開始--- 設計模式:解決某一類問題最行之有效的方法 java中有23種設計模式 今天學習其中一種:單例設計模式:解決一個類在內存只存在一個對象 想要保證對象唯一。 1.為了避免其他程序

設計模式模式

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

設計模式之三:模式式與懶漢式

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

javaSE (三十八設計模式 設計模式式/懶漢式、簡單工廠模式、工廠模式、介面卡模式、模板方法設計模式

1、單例設計模式(餓漢式/懶漢式): 概念:保證類在記憶體中只有一個物件 思路: 私有構造方法,其他類不能再訪問該構造方法了 建立本類物件(就在本類裡建立),將物件的應用作為成員變數,並私有靜態化(在這裡又分為餓漢式和懶漢式,餓漢式直接引用連線物件,而懶漢式在第二步先建

模式懶漢式

餓漢式:載入類的時候,就建立了物件 /** * 餓漢式:載入類的時候,就建立了物件 */ public class Ehanshi { // 建立物件 private static Ehanshi ehanshi = new Ehanshi(); // 無參

模式式 & 懶漢式

建立型模式——單例模式 -目的:使得類的一個物件成為該類系統中的唯一例項。 -定義:一個類有且僅有一個例項,並且自行例項化向整個系統提供。 優點: 1、在記憶體中只有一個物件,節省記憶體空間。 2、

java設計模式建立型模式模式式,懶漢式,執行緒安全,雙重檢查

1.介紹     單例模式是一種常用的軟體設計模式,其定義是單例物件的類只能允許一個例項存在。  2.實現思路與步驟   1).將該類的構造方法定義為私有方法,這樣其他處的程式碼就無法通過呼叫該類的構造方法來例項化該類的物件,只有通過該類提供的靜態

設計模式式,懶漢式1,有執行緒安全問題,2,安全高效

package cn.itcast.mobilesafexian2.test; public class Student { /* (1)單例模式(只需建立一個物件) (外界訪問直接Student.getStudent 即可獲得物件 ) (餓漢式:在載入的時候建立物件{

Java模式式,懶漢式,我更願稱作傳統銷售式,飢餓營銷式

單例模式是一個很經典的設計模式,在java中無處不在。比如spring中的bean注入,工具類的編寫等。但是在剛接觸單例模式時候,我總對這個飽漢式和餓漢式的稱呼理解不好。下面來講一講我自己的理解。1)餓漢模式(傳統銷售式) class A{ private A(){} privat

設計模式-模式式及懶漢式的Java實現

單例模式 單例模式在程式設計中使用的頻率非常之高,其設計的目的是為了在程式中提供唯一一個物件(保證只被構造一次),例如寫入日誌的log物件,windows的工作管理員實現(只能開啟一個)。這裡主要介紹單例模式使用Java的實現(包括餓漢式及懶漢式)。 實現

模式懶漢式的區別

1、餓漢式是在單例類的例項在JVM啟動時就建立好了,懶漢式則是在第一次訪問單例類的例項時才去建立,即可以把餓漢式看成是預載入,懶漢式則為延遲載入; 示例程式碼: public class EagerSingleton { private static final Eag

模式式 執行緒安全 無記憶體洩露

// Singleton.cpp : 定義控制檯應用程式的入口點。 //通過巢狀類實現析構 #include "stdafx.h" #include <iostream>     using namespace std; class Singleton{ pr

設計模式懶漢式

1.設計模式? 設計模式是在大量的實踐中總結和理論化之後優選的程式碼結構,程式設計風格,以及解決問題的思考方式。 2.單例模式的概念?     單例模式,我們首先必須將類在一個虛擬機器中只能產生一個物件,因此應該做到以下幾步:a:私有化構造方法,這樣在該類的外邊就不能用ne

模式懶漢式

常見的單例模式有兩種:餓漢式;懶漢式。 餓漢式程式碼如下: /** * 單例模式之餓漢式 * @author leon * @time 2018年4月27日 下午2:28:14 */ public class HungrySingleton {

c++、設計模式模式懶漢,執行緒安全

單例模式:單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的類一個類只有一個例項。即一個類只有一個物件例項。如何保證一個類只有一個例項並且這個例項易於被訪問呢?定義一個全域性變數可以確保物件隨時都可以被訪

Java 模式懶漢

java單例就是一個類始終只例項化一次 餓漢模式:在程式啟動,類載入的時候就初始化: public class Singleton{ private static Singleton instance = new Singleton(); private S