學習設計模式自然從最簡單的模式入手而最簡單的模式便是Singleton所以第一篇就來所以說Singleton模式看完GOF和Design patterns in Java的書感覺Singleton雖然簡單但是想寫出一個好的Singleton也不是一上來就能寫出來的
Singleton模式的用處自然是保證一個類只有一個唯一的實例在建模中涉及到的只能有一個對象例如Struts中的Action類就是一例除此之外Singleton還使得該對象只有一個全局訪問點這就是SIngleton的作用
說得比較抽象我們來看一個簡單Singleton的C++和Java的代碼
C++ Singleton模式
類定義
class Singleton
{
public:
static Singleton * Instance();
~Singleton();
private:
Singleton();
static Singleton * instance;
};
方法實現
Singleton * Singleton::instance = ;
Singleton::Singleton()
{
}
Singleton::~Singleton()
{
}
Singleton * Singleton::Instance()
{
if (instance == ) {
instance = new Singleton();
}
return instance;
}
Java Singleton模式
public class Singleton {
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
/** *//** Creates a new instance of Singleton */
private Singleton() {
}
}
通過上面的例子可以看出Singleton的實現並不難只要將構造函數訪問域設為私有然後添加一個靜態引用和一個獲得該應用的靜態方法即可其實在C++中定義一個全局靜態變量也可以達到這個效果但是像Java這樣的語言就是能使用Singleton了
上面的程序有一個問題就是只能運行在單線程的環境下為此我在C++上作了個實驗首先#include 在SIngleton::Instance()函數中增加一個Sleep()程序如下
Singleton * Singleton::Instance()
{
if (instance == ) {
Sleep();
instance = new Singleton();
}
return instance;
}
然後在主函數中創建兩個線程程序如下
static Singleton * s = * s = ;
DWORD WINAPI ThreadProc(PVOID)
{
s = Singleton::Instance();
return ;
}
DWORD WINAPI ThreadProc(PVOID)
{
s = Singleton::Instance();
return ;
}
int main(int argc char* argv[])
{
DWORD threadID;
DWORD threadID;
CreateThread(NULL ThreadProc NULL &threadID);
CreateThread(NULL ThreadProc NULL &threadID);
Sleep();
std::cout << s << << s;
return ;
}
這樣修改後在運行程序打印出來的s和s地址就不是同一個地址了結果如下
D EPress any key to continue
可見當在多線程環境下使用這個Singleton就會出現創建不止一個實力的情況所以我們需要給Singleton加鎖請看下面的代碼
C++ Singleton模式
class Singleton
{
public:
static Singleton * Instance();
virtual ~Singleton();
private:
Singleton();
static CMutex mutex;
static Singleton * instance;
};
Singleton * Singleton::instance = ;
CMutex Singleton::mutex;
Singleton::Singleton()
{
}
Singleton::~Singleton()
{
}
Singleton * Singleton::Instance()
{
mutexLock();
if (instance == ) {
Sleep();
instance = new Singleton();
}
mutexUnlock();
return instance;
}
此外需要#include < afxmth>並且在項目設置中要設置動態鏈接MFC庫
Java Singleton模式
public class Singleton {
private static Singleton instance;
private static Object lock = Singletonclass;
public static Singleton getInstance() {
synchronized (lock) {
if (instance == null)
instance = new Singleton();
return instance;
}
}
/** *//** Creates a new instance of Singleton */
private Singleton() {
}
}
運用加鎖就可以解決在多線程環境下使用Singleton模式所帶來的問題了
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27446.html