❶ 什麼是單例模式,舉例說明
定義:
Singleton模式主要作用是保證在java應用程序中,一個類Class只有一個實例存在。
在很多操作中,比如建立目錄 資料庫連接都需要這樣的單線程操作。
還有, singleton能夠被狀態化; 這樣,多個單態類在一起就可以作為一個狀態倉庫一樣向外提供服務,比如,你要論壇中的帖子計數器,每次瀏覽一次需要計數,單態類能否保持住這個計數,並且能synchronize的安全自動加1,如果你要把這個數字永久保存到資料庫,你可以在不修改單態介面的情況下方便的做到。
另外方面,Singleton也能夠被無狀態化。提供工具性質的功能,
Singleton模式就為我們提供了這樣實現的可能。使用Singleton的好處還在於可以節省內存,因為它限制了實例的個數,有利於Java垃圾回收(garbage collection)。
我們常常看到工廠模式中類裝入器(class loader)中也用Singleton模式實現的,因為被裝入的類實際也屬於資源。
如何使用?
一般Singleton模式通常有幾種形式:
public class Singleton {
private Singleton(){}
//在自己內部定義自己一個實例,是不是很奇怪?
//注意這是private 只供內部調用
private static Singleton instance = new Singleton();
//這里提供了一個供外部訪問本class的靜態方法,可以直接訪問
public static Singleton getInstance() {
return instance;
}
}
第二種形式:
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//這個方法比上面有所改進,不用每次都進行生成對象,只是第一次
//使用時生成實例,提高了效率!
if (instance==null)
instance=new Singleton();
return instance; }
}
使用Singleton.getInstance()可以訪問單態類。
上面第二中形式是lazy initialization,也就是說第一次調用時初始Singleton,以後就不用再生成了。
注意到lazy initialization形式中的synchronized,這個synchronized很重要,如果沒有synchronized,那麼使用getInstance()是有可能得到多個Singleton實例。關於lazy initialization的Singleton有很多涉及double-checked locking (DCL)的討論,有興趣者進一步研究。
一般認為第一種形式要更加安全些。
使用Singleton注意事項:
有時在某些情況下,使用Singleton並不能達到Singleton的目的,如有多個Singleton對象同時被不同的類裝入器裝載;在EJB這樣的分布式系統中使用也要注意這種情況,因為EJB是跨伺服器,跨JVM的。
我們以SUN公司的寵物店源碼(Pet Store 1.3.1)的ServiceLocator為例稍微分析一下:
在Pet Store中ServiceLocator有兩種,一個是EJB目錄下;一個是WEB目錄下,我們檢查這兩個ServiceLocator會發現內容差不多,都是提供EJB的查詢定位服務,可是為什麼要分開呢?仔細研究對這兩種ServiceLocator才發現區別:在WEB中的ServiceLocator的採取Singleton模式,ServiceLocator屬於資源定位,理所當然應該使用Singleton模式。但是在EJB中,Singleton模式已經失去作用,所以ServiceLocator才分成兩種,一種面向WEB服務的,一種是面向EJB服務的。
Singleton模式看起來簡單,使用方法也很方便,但是真正用好,是非常不容易,需要對Java的類 線程 內存等概念有相當的了解。
❷ C++剛學單例模式的代碼,對你們來說很簡單,麻煩幫解答一下
#include<iostream>//頭文件
usingnamespacestd;//命名空間
classSingelton//單例類
{
public:
staticSingelton*GetInstance()//提供了一個獲取該單例類實指針的靜態函數
{
if(instance_==NULL)//判斷該實例是否存在
{
instance_=newSingelton;//不存在的話new一個
}
returninstance_;//存在的話直接返回
}
private:
Singelton()//該單例類的構造函數
{
}
staticSingelton*instance_;//該單例類的實例,靜態
};
Singelton*Singelton::instance_;
intmain()
{
Singelton*s=Singelton::GetInstance();//直接獲取該單例類實例,因為不存在,所以這里會new一個
Singelton*s2=Singelton::GetInstance();//直接獲取該單例類實例,因為存在了,所以直接返回,此時s==s2
}
❸ 單例模式有哪兩種設計方法,用文字和代碼分別說明
單例模式(Singleton) ,屬於最常見的設計模式之一,大部分系統都會用到,目的是為了維護系統中唯一的一個實例。
可分為eager模式,示例代碼如下:
Java代碼
1.class EagerSingleton{
2. private static final EagerSingleton m_instance = new EagerSingleton();
3. private EagerSingleton(){}
4. public static EagerSingleton getInstance(){
5. return m_instance;
6. }
7.}
class EagerSingleton{
private static final EagerSingleton m_instance = new EagerSingleton();
private EagerSingleton(){}
public static EagerSingleton getInstance(){
return m_instance;
}
}
和 lazy模式,示例代碼如下:
Java代碼
1.class LazySingleton{
2. private static LazySingleton m_instance = null;
3. private LazySingleton(){}
4. public synchronized static getInstance(){
5. if(m_instance == null){
6. m_instance = new LazySingleton();
7. }
8. return m_instance;
9. }
10.}
class LazySingleton{
private static LazySingleton m_instance = null;
private LazySingleton(){}
public synchronized static getInstance(){
if(m_instance == null){
m_instance = new LazySingleton();
}
return m_instance;
}
}
java源碼中,Runtime.getRuntime()就是單例的一個例子。
單例模式的精神就是整個系統中維護一個實例,推廣開來,如果在一個系統中需要維護多個示例,那麼就產生了多例模式(multiton)。
多例模式(Multiton) ,通過聚集對象了保留自身的多個示例,根據客戶端的參數返回所需要的實例。
示例代碼如下:
Java代碼
1.class Multiton{
2. private final int INSTANCE_SIZE = 10;
3. private static Map instances = new HashMap(INSTANCE_SIZE);
4. private String name;
5. private Multiton(){}
6. private Multiton(String name){
7. this.name = name;
8. }
9. public synchronized static getInstance(String name){
10. if(instances.containsKey(name)){
11. return instances.get(name);
12. }
13. else{
14. ins = new Multiton(name);
15. instances.put(name, ins);
16. return ins;
17. }
18. }
19.}
class Multiton{
private final int INSTANCE_SIZE = 10;
private static Map instances = new HashMap(INSTANCE_SIZE);
private String name;
private Multiton(){}
private Multiton(String name){
this.name = name;
}
public synchronized static getInstance(String name){
if(instances.containsKey(name)){
return instances.get(name);
}
else{
ins = new Multiton(name);
instances.put(name, ins);
return ins;
}
}
}
[nextpage]
一個實用的例子就是KeyGenerator, 示例代碼如下:
Java代碼
1.class KeyGenerator{
2. private final int POOL_SIZE = 20;
3. private static Map instances = new HashMap(16);
4. private KeyInfo keyinfo;
5. private KeyGenerator(){}
6. private KeyGenerator(String keyName){
7. this.keyinfo = new KeyInfo(POOL_SIZE, keyName);
8. }
9. public synchronized static getInstance(String keyName){
10. if(instances.containsKey(keyName)){
11. return (KeyGenerator)instances.get(keyName);
12. }
13. else{
14. keyGen = new KeyGenerator(keyName);
15. instances.put(name, keyGen);
16. return keyGen;
17. }
18. }
19. public synzhronized int getNextKey(){
20. return keyinfo.getNextKey();
21. }
22. }
class KeyGenerator{
private final int POOL_SIZE = 20;
private static Map instances = new HashMap(16);
private KeyInfo keyinfo;
private KeyGenerator(){}
private KeyGenerator(String keyName){
this.keyinfo = new KeyInfo(POOL_SIZE, keyName);
}
public synchronized static getInstance(String keyName){
if(instances.containsKey(keyName)){
return (KeyGenerator)instances.get(keyName);
}
else{
keyGen = new KeyGenerator(keyName);
instances.put(name, keyGen);
return keyGen;
}
}
public synzhronized int getNextKey(){
return keyinfo.getNextKey();
}
}
❹ 在Java中,單例設計模式是什麼意思有什麼優勢
單例模式:保證一個類在使用過程中,只有一個實例。
優勢就是單例模式的作用,這個類永遠只有一個實例。
還在於可以節省內存,因為它限制了實例的個數,有利於Java垃圾回收。
❺ 什麼叫單例模式,如何實現,有什麼作用
就是只有一個實例,最簡單的單例模式可以用static來實現。
比如下面的_Context變數就是用了單利模式,下面的代碼就是外面想調用_Context時,如果_Context已經實例化,那麼直接返回,如果沒實例化,就實例化它再返回。全局只有一個_Context
比如
public
class
EESGateway
{
private
static
EESDatabaseDataContext
_Context
=
null;
//EESDatabasDataContex
Instance
private
const
string
databaseName
=
"EESDatabase";
//Database
name
///
///
Return
EESDatabaseDataContext
instance.
///
///
EESDatabaseDataContext
instance
public
static
EESDatabaseDataContext
DataContext()
{
if
(_Context
==
null)
{
lock
(typeof(EESGateway))
{
//formate
a
new
string
to
store
the
connectionString
String
connectionString
=
ConfigurationManager.ConnectionStrings["EESDatabase"].ConnectionString;
//create
a
dataContext
using
the
connectionString
above
_Context
=
new
EESDatabaseDataContext(connectionString);
}
}
return
_Context;
}
}
❻ 如何寫一個簡單的單例模式
一、基本的實現思路:
單例的實現主要是通過以下兩個步驟:
1、將該類的構造方法定義為私有方法,這樣其他處的代碼就無法通過調用該類的構造方法來實例化該類的對象,只有通過該類提供的靜態方法來得到該類的唯一實例;
2、在該類內提供一個靜態方法,當我們調用這個方法時,如果類持有的引用不為空就返回這個引用,如果類保持的引用為空就創建該類的實例並將實例的引用賦予該類保持的引用。
二、示範如下:
1、枚舉實現單例:
(6)單例模式源碼分析擴展閱讀:
一、單列模式簡介:
單例模式是設計模式中最簡單的形式之一。這一模式的目的是使得類的一個對象成為系統中的唯一實例。要實現這一點,可以從客戶端對其進行實例化開始。因此需要用一種只允許生成對象類的唯一實例的機制,「阻止」所有想要生成對象的訪問。使用工廠方法來限制實例化過程。這個方法應該是靜態方法(類方法),因為讓類的實例去生成另一個唯一實例毫無意義。
二、懶漢與餓漢:
1、懶漢方式:指全局的單例實例在第一次被使用時構建。
2、餓漢方式:指全局的單例實例在類裝載時構建。
三、單例模式的三要點:
1、某個類只能有一個實例。
2、它必須自行創建這個實例。
3、它必須自行向整個系統提供這個實例。
四、優缺點:
1、優點:
①實例控制:單例模式會阻止其他對象實例化其自己的單例對象的副本,從而確保所有對象都訪問唯一實例。
②靈活性:因為類控制了實例化過程,所以類可以靈活更改實例化過程。
2、缺點:
①開銷:雖然數量很少,但如果每次對象請求引用時都要檢查是否存在類的實例,將仍然需要一些開銷。可以通過使用靜態初始化解決此問題。
②可能的開發混淆:使用單例對象(尤其在類庫中定義的對象)時,開發人員必須記住自己不能使用new關鍵字實例化對象。因為可能無法訪問庫源代碼,因此應用程序開發人員可能會意外發現自己無法直接實例化此類。
③對象生存期:不能解決刪除單個對象的問題。在提供內存管理的語言中(例如基於.NET Framework的語言),只有單例類能夠導致實例被取消分配,因為它包含對該實例的私有引用。在某些語言中(如 C++),其他類可以刪除對象實例,但這樣會導致單例類中出現懸浮引用。
❼ 關於單例模式,如何理解
單例模式就是 :
1、類的構造函數為private,即外部程序不能通過new關鍵字創建對象的實例
2、類中提供一個private static的 類變數引用 ;
3、單例類中提供靜態方法 定義為 public static 的方法獲取一個類的實例 ;
4、靜態方法返回 類的引用,即 第2點中的 私有 靜態變數 。
私有靜態變數可以 定義的時候初始化 ,也可以 在第一次使用的時候,即調用AA.getInstanc()方法中判斷 靜態變數是否為空在初始化 。
❽ java 單例模式這個要怎麼理解
單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。
這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象。
注意:
1、單例類只能有一個實例。
2、單例類必須自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。
介紹
意圖:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
主要解決:一個全局使用的類頻繁地創建與銷毀。
何時使用:當您想控制實例數目,節省系統資源的時候。
如何解決:判斷系統是否已經有這個單例,如果有則返回,如果沒有則創建。
關鍵代碼:構造函數是私有的。
應用實例:
1、一個班級只有一個班主任。
2、Windows 是多進程多線程的,在操作一個文件的時候,就不可避免地出現多個進程或線程同時操作一個文件的現象,所以所有文件的處理必須通過唯一的實例來進行。
3、一些設備管理器常常設計為單例模式,比如一個電腦有兩台列印機,在輸出的時候就要處理不能兩台列印機列印同一個文件。
優點:
1、在內存里只有一個實例,減少了內存的開銷,尤其是頻繁的創建和銷毀實例(比如管理學院首頁頁面緩存)。
2、避免對資源的多重佔用(比如寫文件操作)。
缺點:沒有介面,不能繼承,與單一職責原則沖突,一個類應該只關心內部邏輯,而不關心外面怎麼樣來實例化。
使用場景:
1、要求生產唯一序列號。
2、WEB 中的計數器,不用每次刷新都在資料庫里加一次,用單例先緩存起來。
3、創建的一個對象需要消耗的資源過多,比如 I/O 與資料庫的連接等。
注意事項:getInstance() 方法中需要使用同步鎖 synchronized (Singleton.class) 防止多線程同時進入造成 instance 被多次實例化。
❾ 怎麼理解python單例模式
在聊這之前我們首先要明確的是,單例模式在實際中的意義以及在python中具有實現的價值?
當前,相信有很多人支持單例模式,也有不少人反對,尤其是在python中,目前依舊具有很大的爭議性。我們要在評論之前首先要了解單例模式
什麼是單例模式?
顧名思義:就是單個模式
單例模式是一種常見的軟體設置模式,在它的核心結構中只包含一個被稱為單例類的特殊類,通過單例模式可以保證系統中的一個類只有一個實例而且該實例易於外界訪問,從而方便對實例個數的控制並節約系統資源。如果希望在系統中某個對象只能存在一個,單例模式是最好的解決方案。
單例模式的要點有三類
某個類只能有一個實例
它必須創建這個實例
它必須自行向整個系統提供這個實例
但是從具體角度實現來說的話,又可以分為三點
單例模式的類只能提供私有的構造函數
類定義中含有一個該類的靜態私有對象
該類提供了一個靜態的共有的函數用於創建或獲取它本身的靜態私有對象
一、實例控制
單例模式會阻止其他對象實例化其自己的單例對象的副本,從而確保所有對象都訪問唯一實例。
二、靈活性
因為類控制了實例化過程,所以類可以靈活更改實例化過程。
缺點:
一、開銷
雖然數量很少,但如果每次對象請求引用時都要檢查是否存在類的實例,將仍然需要一些開銷。可以通過使用靜態初始化解決此問題。
二、可能的開發混淆
使用單例對象(尤其在類庫中定義的對象)時,開發人員必須記住自己不能使用new關鍵字實例化對象。因為可能無法訪問庫源代碼,因此應用程序開發人員可能會意外發現自己無法直接實例化此類。
三、對象生存期
不能解決刪除單個對象的問題。在提供內存管理的語言中(例如基於.NET Framework的語言),只有單例類能夠導致實例被取消分配,因為它包含對該實例的私有引用。在某些語言中(如 C++),其他類可以刪除對象實例,但這樣會導致單例類中出現懸浮引用。
常用幾種方式
通過面向的特性,簡單的構造出單例模式
123456789101112131415當用於WEB界面時,單例模式的簡單運用
web 單例模式
不過我們需要注意的是:
特殊方法__new__是一個元構造程序,每當一個對象必須被factory類實例化時,就將調用它。__new__方法必須返回一個類的實例,因此它可以在對象創建之前或之後修改類。
因為__init__在子類中不會被隱式調用,所以__new__可以用來確定已經在整個類層次完成了初始化構造。__new__是對於對象狀態隱式初始化需求的回應,使得可以在比__init__更低的一個層次上定義一個初始化,這個初始化總是會被調用。
與__init__()相比__new__()方法更像一個真正的構造器。隨著類和類型的統一,用戶可以對內建類型進行派生,因此需要一種途徑來實例化不可變對象,比如派生字元串,在這種情況下解釋器則調用類的__new__()方法,一個靜態方法,並且傳入的參數是在類實例化操作時生成的。__new__()會調用父類的__new__()來創建對象(向上代理)
·__new__必須返回一個合法的實例,這樣解釋器在調用__init__()時,就可以吧這個實例作為self傳給他。調用父類的__new__()來創建對象,正向其他語言使用new關鍵字一樣
總結
單利模式存在的目的是保證當前內存中僅存在單個實例,避免內存浪費!!!
❿ java中的單例模式的代碼怎麼寫
單例模式(Singleton) ,屬於最常見的設計模式之一,大部分系統都會用到,目的是為了維護系統中唯一的一個實例。
可分為eager模式,示例代碼如下:
Java代碼
1.class EagerSingleton{
2. private static final EagerSingleton m_instance = new EagerSingleton();
3. private EagerSingleton(){}
4. public static EagerSingleton getInstance(){
5. return m_instance;
6. }
7.}
class EagerSingleton{
private static final EagerSingleton m_instance = new EagerSingleton();
private EagerSingleton(){}
public static EagerSingleton getInstance(){
return m_instance;
}
}
和 lazy模式,示例代碼如下:
Java代碼
1.class LazySingleton{
2. private static LazySingleton m_instance = null;
3. private LazySingleton(){}
4. public synchronized static getInstance(){
5. if(m_instance == null){
6. m_instance = new LazySingleton();
7. }
8. return m_instance;
9. }
10.}
class LazySingleton{
private static LazySingleton m_instance = null;
private LazySingleton(){}
public synchronized static getInstance(){
if(m_instance == null){
m_instance = new LazySingleton();
}
return m_instance;
}
}
java源碼中,Runtime.getRuntime()就是單例的一個例子。
單例模式的精神就是整個系統中維護一個實例,推廣開來,如果在一個系統中需要維護多個示例,那麼就產生了多例模式(multiton)。
多例模式(Multiton) ,通過聚集對象了保留自身的多個示例,根據客戶端的參數返回所需要的實例。
示例代碼如下:
Java代碼
1.class Multiton{
2. private final int INSTANCE_SIZE = 10;
3. private static Map instances = new HashMap(INSTANCE_SIZE);
4. private String name;
5. private Multiton(){}
6. private Multiton(String name){
7. this.name = name;
8. }
9. public synchronized static getInstance(String name){
10. if(instances.containsKey(name)){
11. return instances.get(name);
12. }
13. else{
14. ins = new Multiton(name);
15. instances.put(name, ins);
16. return ins;
17. }
18. }
19.}
class Multiton{
private final int INSTANCE_SIZE = 10;
private static Map instances = new HashMap(INSTANCE_SIZE);
private String name;
private Multiton(){}
private Multiton(String name){
this.name = name;
}
public synchronized static getInstance(String name){
if(instances.containsKey(name)){
return instances.get(name);
}
else{
ins = new Multiton(name);
instances.put(name, ins);
return ins;
}
}
}
[nextpage]
一個實用的例子就是KeyGenerator, 示例代碼如下:
Java代碼
1.class KeyGenerator{
2. private final int POOL_SIZE = 20;
3. private static Map instances = new HashMap(16);
4. private KeyInfo keyinfo;
5. private KeyGenerator(){}
6. private KeyGenerator(String keyName){
7. this.keyinfo = new KeyInfo(POOL_SIZE, keyName);
8. }
9. public synchronized static getInstance(String keyName){
10. if(instances.containsKey(keyName)){
11. return (KeyGenerator)instances.get(keyName);
12. }
13. else{
14. keyGen = new KeyGenerator(keyName);
15. instances.put(name, keyGen);
16. return keyGen;
17. }
18. }
19. public synzhronized int getNextKey(){
20. return keyinfo.getNextKey();
21. }
22. }
class KeyGenerator{
private final int POOL_SIZE = 20;
private static Map instances = new HashMap(16);
private KeyInfo keyinfo;
private KeyGenerator(){}
private KeyGenerator(String keyName){
this.keyinfo = new KeyInfo(POOL_SIZE, keyName);
}
public synchronized static getInstance(String keyName){
if(instances.containsKey(keyName)){
return (KeyGenerator)instances.get(keyName);
}
else{
keyGen = new KeyGenerator(keyName);
instances.put(name, keyGen);
return keyGen;
}
}
public synzhronized int getNextKey(){
return keyinfo.getNextKey();
}
}