個人對單例模式的一點理解

2021-09-12 02:27:10 字數 2995 閱讀 2994

(如有誤解請指出,感激不盡)

單例模式是一種常用的軟體設計模式。在它的核心結構中只包含乙個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的乙個類只有乙個例項。即乙個類只有乙個物件例項。

在某些場景下,我們可能只需要建立乙個例項,並且確保其他所有的物件訪問時都是這乙個例項,然後利用這個例項來控制整個系統。

適用場景

windows的任務管理器(task manager)。

windows的**站(recycle bin)。

外部印表機的管理:當一台電腦連線多個印表機的時候,也只有乙個列印後台處理服務(printerspooler),以避免多個印表機同時列印同乙個檔案。

部分軟體的一些屬性檔案的存放和呼叫,用乙個物件來統一管理。

目標:保證乙個類中只有乙個例項。

思路:外部不可建立單例類的例項物件,單例類的構造方法必須自己定義為私有。

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

在單例類提供乙個靜態方法,在呼叫該方法時返回給其他物件唯一例項。

餓漢式:單例例項在載入類的時候就建立。

public

class

singletonhungary

// 私有化單例類構造器

public

static singletonhungary getinstance()

}

優點:在類載入的時候就完成了例項建立,避免了多執行緒同步的問題。執行緒安全,執行效率高。

缺點:只要載入了該類,例項物件就建立了。資源效率不高,而且可能getinstance()永遠不會執行使用,造成資源的浪費。

懶漢式:在需要時建立單例例項。

public

class

singletonlazy

// 私有化單例類構造器

public

static singletonlazy getinstance()

return instance;

//訪問該靜態方法時返回單例類例項

}}

優點:資源利用率高,避免了在使用該類其他靜態方法或載入該類時創造例項。起到了懶載入(lazy loading)的作用。在單執行緒下安全。

缺點:在多個執行緒同時訪問到該類getinstance()方法時,可能會同時生成多個例項,與我們的目的衝突。

懶漢式(嘗試解決):針對多個執行緒同時訪問產生多個例項的情況做調整優化。

public

class

singletonlazy

// 私有化單例類構造器

public

static singletonlazy getinstance()

}return instance;

//返回單例類例項

}}

這種情況看似利用synchronized()方法解決了多執行緒同步的問題,但其實和第2種情況一樣,如果同時有多個執行緒進入到if (instance == null)這裡,即使下面的內容加了鎖,已經同時進入的執行緒還是會挨個執行建立例項,產生多個例項。

這種方法並不能解決執行緒不安全的問題,不可用

懶漢式(執行緒安全版本):

public

class

singletonlazy

// 私有化單例類構造器

public

static singletonlazy getinstance()

}return instance;

//返回單例類例項

}}

懶漢式(執行緒安全改良版):雙重檢測

public

class

singletonlazy

// 私有化單例類構造器

public

static singletonlazy getinstance()

}}return instance;

//返回單例類例項

}}

優點:保證了單例的前提下提高了執行效率,執行緒安全且效率較高。

缺點:可能會產生重排序問題。

理解重排序:

筆者認為這篇部落格寫的非常詳細,讀者可自行跳轉理解重排序問題,本文不再過多闡述。

懶漢式(執行緒安全終極版):volatile關鍵字

volatile關鍵字簡直是為了這類問題量身定做的。**如下

public

class

singletonlazy

// 私有化單例類構造器

public

static singletonlazy getinstance()

}}return instance;

//返回單例類例項

}}

懶漢式:利用靜態內部類實現執行緒安全的延遲載入

public

class

singletonlazy

private

singletonlazy()

public

static singletonlazy getinstance()

}

優點:資源利用率高,而且執行緒安全。執行緒安全原理和餓漢式相似。不再過多闡述。

缺點:第一次載入時稍慢。

列舉:

public

enum singletonenum

public

static

void

main

(string[

] args)

}

列舉的建立由jvm保證,所以不會產生併發問題,構造器自動私有,外部不能建立只能引用。

列舉的其餘特性筆者暫時不夠了解,不在此多做介紹。

本文介紹了餓漢式、多種懶漢式和列舉等單例模式的常用寫法。在懶漢式中指出了一些常見的雷區。

最後,推薦使用的幾種方法為:餓漢式、懶漢式(執行緒安全最終版,含volatile關鍵字)、懶漢式(靜態內部類方法)、列舉。

關於單例的一點自我理解

單例,個人理解就是乙個model類,例項,必須乙個類只有乙個例項,他的宗旨是物件只建立一次。意思就是,用類建立物件的時候,先判斷物件是否存在,如果存在就用已有的不再建立新的,如果沒有就建立新的物件。一般程式執行起來只第一次建立好了直到程式退出結束之間,這個單例都一直存在,單例是一直在用物件在操作。所...

對單例模式的理解

單例模式的三個特點 1 構造方法私有化 2 例項化的變數引用私有化 3 獲取例項的方法共有 什麼是單例 確保這個類在記憶體中只會存在乙個物件,而且自行例項化並向整個應用系統提供這個例項。應用的場景 建立乙個物件會消耗過多的資源,比如訪問io和資料庫 有哪幾種方式 推薦用靜態內部類或加了volatil...

單例模式的一點小見解

還是很心煩,一面試就問單例模式,單例模式的。那麼只能看看啥是單例模式 當這個類的物件在多個地方建立的時候,使得內部的方法多次呼叫,但是希望只要乙個物件操作這個方法,或者不希望多個地方同時呼叫這個方法,需要保持這個方法的單一性質,就用單利模式吧。那麼單例模式怎麼實現的呢,關於這個網上有2種,3種,5種...