singleton 模式的多线程安全创建

      单例模式是通过类的静态函数直接获取对象,并且通过静态变量的特性保证一个进程只有一个该对象。这种模式的类在UML 里与其他类关系通常只是表现为“依赖”关系而已,应该说这个模式可以在设计上一定程度上帮我们解耦。其通常设计如下:


class A{

public:

    static A* CreateInstance()

   {

      static A* pInstance =NULL;

    if( pInstance==NULL)

       pInstance= new A();


   return pInstance;

  } 

};


但createinstance 函数可能在多线程下出现 同时被new 的情况,这个就不符合我们的想法了。

为了在多线程下正确使用,改进如下: 


class A {


static A* CreateInstance()

{

 

      static A* pInstance =NULL;

    if( pInstance==NULL)

    {

         EnterCriticSection(&g_cs);

         if(pInstance==NULL)

            {

            pInstance = new A(); 

         }

       LeaveCriticSection(&g_cs);

   }

  return pInstance ;

};

 代码里 我们必须连续检查2次pInstance变量,因为第一次判断 与entercriticSection 之间 ,pInstance 的值是有可能变化的。

 

上面使用criticalSection 变量,太过繁琐,我们使用 Interlock 函数来简化处理:

class A{

public:

    static A* CreateInstance()

   {

   volatile    static A* pInstance =NULL;

    if( pInstance==NULL)

     {

              A * pnew = new A();

               if(InterlockedCompareExchangePointer((volatile PVOID *)&pInstance,pnew,NULL) !=NULL)
                { // 失败,表示别的线程抢在当前线程前创建了该对象
                    delete pnew;
                }

    } 

   return (static A*) pInstance; 

  } 

};


这个里我们再通过模板构建一个通用的singleton创建器:

template<class T>
class SingleCreator {

public:
    static T* CreateInstance()
    {

   volatile    static T* pInstance =NULL;

    if( pInstance==NULL)

     {

             T * pnew = new A();

               if(InterlockedCompareExchangePointer((volatile PVOID *)&pInstance,pnew,NULL) !=NULL)
                { // 失败,表示别的线程抢在当前线程前创建了该对象
                    delete pnew;
                }

    } 

   return (static T*) pInstance; 
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值