單例模式

單例模式（Singleton pattern），也叫單子模式，是一種常用的軟體設計模式，屬於建立型模式的一種。在應用這個模式時，單例物件的類必須保證只有一個例項存在。許多時候整個系統只需要擁有一個的全域性物件，這樣有利於我們協調系統整體的行為。比如在某個伺服器程式中，該伺服器的配置資訊存放在一個檔案中，這些配置資料由一個單例物件統一讀取，然後服務程序中的其他物件再透過這個單例物件獲取這些配置資訊。這種方式簡化了在複雜環境下的配置管理。

實現單例模式的思路是：一個類能返回物件一個引用（永遠是同一個）和一個獲得該例項的方法（必須是靜態方法，通常使用 getInstance 這個名稱）；當我們呼叫這個方法時，如果類持有的引用不為空就返回這個引用，如果類保持的引用為空就建立該類的例項並將例項的引用賦予該類保持的引用；同時我們還將該類的建構函式定義為私有方法，這樣其他處的程式碼就無法透過呼叫該類的建構函式來例項化該類的物件，只有透過該類提供的靜態方法來得到該類的唯一例項。

單例模式在多執行緒的應用場合下必須小心使用。如果當唯一例項尚未建立時，有兩個執行緒同時呼叫建立方法，那麼它們同時沒有檢測到唯一例項的存在，從而同時各自建立了一個例項，這樣就有兩個例項被構造出來，從而違反了單例模式中例項唯一的原則。 解決這個問題的辦法是為指示類是否已經例項化的變數提供一個互斥鎖（雖然這樣會降低效率）。

構建方式

通常單例模式在 Java 語言中，有兩種構建方式：

懶漢方式。指全域性的單例例項在第一次被使用時構建。
餓漢方式。指全域性的單例例項在類裝載時構建。

例子

2.1 Java

在 Java 語言中，單例模式（餓漢模式）應用的例子如下述程式碼所示：

public class Singleton {private static final Singleton INSTANCE = new Singleton ;

// Private constructor suppresses

//default public constructor

private Singleton ;

public static Singleton getInstance {return INSTANCE;}

}

在 Java 程式語言中，單例模式（懶漢模式）應用的例子如下述程式碼所示 （此種方法只能用在 JDK5 及以後版本（注意 INSTANCE 被宣告為 volatile），之前的版本使用 “雙重檢查鎖” 會發生非預期行為）：

public class Singleton {

private static volatile Singleton INSTANCE = null;

// Private constructor suppresses

//default public constructor

private Singleton ;

//Thread safe and performance promote

public static Singleton getInstance {if (INSTANCE == null){synchronized (Singleton.class){

// When more than two threads run into the first null check same time,

//to avoid instanced more than one time, it needs to be checked again.

if (INSTANCE == null){INSTANCE = new Singleton ;

}

}

}

return INSTANCE;

}

}

2.2 C++

在 C++ 程式語言中，單例模式應用的例子如下述程式碼所示（這裡僅僅提供一個示例；由於加入了鎖，這程式碼是執行緒安全的）：

//...

class lock

{

public:

lock ;

lock (lock const & l);

~lock ;

lock & operator =(lock const & l);

void request ;

void release ;

//...

};

lock::lock

{//...}

//...

lock::~lock

{//...}

//...

void lock::request

{//...}

void lock::release

{//...}

//...

//assumes DATATYPE_ has a default constructor

template

class singleton

{

public:

static DATATYPE_ * request ;

static void release ;

private:

singleton ;

singleton (singleton const & s);

~singleton ;

singleton & operator =(singleton const & s);

static DATATYPE_ * pointer;

static lock mutex;

//...

};

template

DATATYPE_ * singleton::pointer = nullptr;

template

lock singleton::mutex;

template

DATATYPE_ * singleton::request

{if (singleton::pointer == nullptr)

{singleton::mutex.request ;

if (singleton::pointer == nullptr)

{singleton::pointer = new DATATYPE_;}

singleton::mutex.release ;}

return singleton::pointer;

}

template

void singleton::release

{if (singleton::pointer != nullptr)

{singleton::mutex.request ;

if (singleton::pointer != nullptr)

{

delete singleton::pointer;

singleton::pointer = nullptr;

}

singleton::mutex.release ;}

}

template

singleton::singleton

{//...}

//...

int main

{

int * s;

s = singleton::request ;

//...

singleton::release ;

return 0;

}

2.3 GO

GO 語言中的單例模式:

var _instance *service

var once sync.Once

type service struct {Name string}

func Service *service {once.Do (func {_instance = &service

})

	return _instance

}

func (this *service) Startup

func (this *service) Stop

func (this *service) Restart

2.4 Objective-C

OC 語言中的單例模式:

@interface Control : NSObject

+(id) getShare;

@end

static Control *mControl;

@implementation Control

+(id) getShare

{if (mControl == nil) {mControl = Control alloc init;}

return mControl;

}

-(id) init {// 你需要初始化的屬性。。。}

@end

2.5 PHP

PHP 語言中的單例模式: