当前位置:首页 > 资讯 > info6 > 正文

singleton 模式的多线程安全创建

发表于: 2013-11-27   作者:cenchure   来源:转载   浏览:
摘要:     单例模式是通过类的静态函数直接获取对象,并且通过静态变量的特性保证一个进程只有一个该对象。这种模式的类在UML里与其他类关系通常只是表现为“依赖”关系而已,应该说这个模式可以在设计上一定程度上帮我们解耦。其通常设计如下:classA{public:   staticA*CreateInstance()  {     staticA*pInstance=NULL;   if(pInstanc

      单例模式是通过类的静态函数直接获取对象,并且通过静态变量的特性保证一个进程只有一个该对象。这种模式的类在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; 
    }
};


singleton 模式的多线程安全创建

编辑推荐
Singleton:Ensure a class only has one instance, and provide a global point of access to it.
单例模式是一种创建型的模式,适用于 全局只有一个对象的类, 结构图 只有一个静态 实例变量 和一个
Spring 中管理的 Bean 实例默认情况下是单例的(sigleton 类型),但 Spring 中的单例并不会影响应
概括 名称 Singleton 结构 动机 保证一个类仅有一个实例,并提供一个访问它的全局访问点。 适用性
作用: Singleton单例模式目的在于确保一个类只有唯一的一个实例,并且这个唯一实例只有一个全局访
1、结构图 2、代码 using System; namespace DesignPattern.CreationalPattern { /// <summary&g
1. 标准的实现 -----------------------------Singleton.h------------------------------- #inndef
1. 标准的实现 -----------------------------Singleton.h------------------------------- #inndef
1. 标准的实现 -----------------------------Singleton.h------------------------------- #inndef
模式概述 个人认为 Singleton模式是所有设计试中最简单,最常见,也是最容易实现的,因此,设计模式
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号