设计模式学习笔记(一)——Singleton

        学习设计模式,自然从最简单的模式入手,而最简单的模式便是Singleton。所以第一篇就来所以说Singleton。看完GOF和Design patterns in Java的书,感觉Singleton虽然简单,但是想写出一个好的Singleton也不是一上来就能写出来的。
       Singleton的用处自然是保证一个类只有一个唯一的实例。在建模中涉及到的只能有一个对象,例如Struts中的Action类就是一例。除此之外,Singleton还使得该对象只有一个全局访问点。这就是SIngleton的作用。
       说得比较抽象,我们来看一个简单Singleton的C++和Java的代码:
C++:
类定义:
class  Singleton  
{
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;
}
Java:
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 <windows.h>。在SIngleton::Instance()函数中增加一个Sleep(1000),程序如下:
Singleton  *  Singleton::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;
}
这样修改后在运行程序,打印出来的s1和s2地址就不是同一个地址了。结果如下:
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;
}
;
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;
}
此外需要#include <afxmt.h>,并且在项目设置中要设置动态链接MFC库。
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() {
    }

}
运用加锁就可以解决在多线程环境下使用Singleton所带来的问题了。程序可能还有没考虑到的方面,希望大家指正。谢谢。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值