学习设计模式自然从最简单的模式入手而最简单的模式便是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模式所带来的问题了 |