学习设计模式,自然从最简单的模式入手,而最简单的模式便是Singleton。所以第一篇就来所以说Singleton。看完GOF和Design patterns in Java的书,感觉Singleton虽然简单,但是想写出一个好的Singleton也不是一上来就能写出来的。
Singleton的用处自然是保证一个类只有一个唯一的实例。在建模中涉及到的只能有一个对象,例如Struts中的Action类就是一例。除此之外,Singleton还使得该对象只有一个全局访问点。这就是SIngleton的作用。
说得比较抽象,我们来看一个简单Singleton的C++和Java的代码:
C++:
类定义:
方法实现:
Java:
通过上面的例子可以看出,Singleton的实现并不难,只要将构造函数访问域设为私有,然后添加一个静态引用和一个获得该应用的静态方法即可。其实在C++中定义一个全局静态变量也可以达到这个效果,但是像Java这样的语言就是能使用Singleton了。
上面的程序有一个问题,就是只能运行在单线程的环境下。为此我在C++上作了个实验。首先#include <windows.h>。在SIngleton::Instance()函数中增加一个Sleep(1000),程序如下:
然后在主函数中创建两个线程,程序如下:
这样修改后在运行程序,打印出来的s1和s2地址就不是同一个地址了。结果如下:
00372D68 00372E68Press any key to continue
可见当在多线程环境下使用这个Singleton就会出现创建不止一个实力的情况,所以我们需要给Singleton加锁。请看下面的代码。
C++:
此外需要#include <afxmt.h>,并且在项目设置中要设置动态链接MFC库。
Java:
运用加锁就可以解决在多线程环境下使用Singleton所带来的问题了。程序可能还有没考虑到的方面,希望大家指正。谢谢。
Singleton的用处自然是保证一个类只有一个唯一的实例。在建模中涉及到的只能有一个对象,例如Struts中的Action类就是一例。除此之外,Singleton还使得该对象只有一个全局访问点。这就是SIngleton的作用。
说得比较抽象,我们来看一个简单Singleton的C++和Java的代码:
C++:
类定义:
class
Singleton
{
public:
static Singleton * Instance();
~Singleton();
private:
Singleton();
static Singleton * instance;
} ;
{
public:
static Singleton * Instance();
~Singleton();
private:
Singleton();
static Singleton * instance;
} ;
Singleton
*
Singleton::instance
=
0
;
Singleton::Singleton()
{
}
Singleton:: ~ Singleton()
{
}
Singleton * Singleton::Instance()
{
if (instance == 0) {
instance = new Singleton();
}
return instance;
}
Singleton::Singleton()
{
}
Singleton:: ~ Singleton()
{
}
Singleton * Singleton::Instance()
{
if (instance == 0) {
instance = new Singleton();
}
return instance;
}
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() {
}
}
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null)
instance = new Singleton();
return instance;
}
/** Creates a new instance of Singleton */
private Singleton() {
}
}
上面的程序有一个问题,就是只能运行在单线程的环境下。为此我在C++上作了个实验。首先#include <windows.h>。在SIngleton::Instance()函数中增加一个Sleep(1000),程序如下:
Singleton
*
Singleton::Instance()
{
if (instance == 0) {
Sleep(1000);
instance = new Singleton();
}
return instance;
}
{
if (instance == 0) {
Sleep(1000);
instance = new Singleton();
}
return instance;
}
static
Singleton
*
s1
=
0
,
*
s2
=
0
;
DWORD WINAPI ThreadProc1(PVOID)
{
s1 = Singleton::Instance();
return 0;
}
DWORD WINAPI ThreadProc2(PVOID)
{
s2 = Singleton::Instance();
return 0;
}
int main( int argc, char * argv[])
{
DWORD threadID1;
DWORD threadID2;
CreateThread(NULL, 0, ThreadProc1, NULL, 0, &threadID1);
CreateThread(NULL, 0, ThreadProc2, NULL, 0, &threadID2);
Sleep(10000);
std::cout << s1 << " " << s2;
return 0;
}
DWORD WINAPI ThreadProc1(PVOID)
{
s1 = Singleton::Instance();
return 0;
}
DWORD WINAPI ThreadProc2(PVOID)
{
s2 = Singleton::Instance();
return 0;
}
int main( int argc, char * argv[])
{
DWORD threadID1;
DWORD threadID2;
CreateThread(NULL, 0, ThreadProc1, NULL, 0, &threadID1);
CreateThread(NULL, 0, ThreadProc2, NULL, 0, &threadID2);
Sleep(10000);
std::cout << s1 << " " << s2;
return 0;
}
00372D68 00372E68Press any key to continue
可见当在多线程环境下使用这个Singleton就会出现创建不止一个实力的情况,所以我们需要给Singleton加锁。请看下面的代码。
C++:
class
Singleton
{
public:
static Singleton * Instance();
virtual ~Singleton();
private:
Singleton();
static CMutex mutex;
static Singleton * instance;
} ;
{
public:
static Singleton * Instance();
virtual ~Singleton();
private:
Singleton();
static CMutex mutex;
static Singleton * instance;
} ;
Singleton
*
Singleton::instance
=
0
;
CMutex Singleton::mutex;
Singleton::Singleton()
{
}
Singleton:: ~ Singleton()
{
}
Singleton * Singleton::Instance()
{
mutex.Lock();
if (instance == 0) {
Sleep(1000);
instance = new Singleton();
}
mutex.Unlock();
return instance;
}
CMutex Singleton::mutex;
Singleton::Singleton()
{
}
Singleton:: ~ Singleton()
{
}
Singleton * Singleton::Instance()
{
mutex.Lock();
if (instance == 0) {
Sleep(1000);
instance = new Singleton();
}
mutex.Unlock();
return instance;
}
Java:
public
class
Singleton
{
private static Singleton instance;
private static Object lock = Singleton.class;
public static Singleton getInstance() {
synchronized (lock) {
if (instance == null)
instance = new Singleton();
return instance;
}
}
/** Creates a new instance of Singleton */
private Singleton() {
}
}
private static Singleton instance;
private static Object lock = Singleton.class;
public static Singleton getInstance() {
synchronized (lock) {
if (instance == null)
instance = new Singleton();
return instance;
}
}
/** Creates a new instance of Singleton */
private Singleton() {
}
}