Chinaunix首页 | 论坛 | 博客
  • 博客访问: 17408
  • 博文数量: 22
  • 博客积分: 920
  • 博客等级: 准尉
  • 技术积分: 220
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-27 15:19
文章分类

全部博文(22)

文章存档

2010年(22)

我的朋友
最近访客

分类: C/C++

2010-03-27 16:01:09

An essay about double-check

     In some situations, we often use singleton pattern to ensure only one instance of the object would be created in our system. The code is often like this: 

class Singleton
{
private:
    static Singleton *instance;

public:
    static Singleton* getInstance();

private:
    Singleton();//declare the constructor to be private in order to avoid to be called by others.

};

 

Singleton *Singleton::instance = NULL;

//v1:

Singleton* Singleton::getInstance()
{
    if(NULL == instance) //check statement

    {
        //object production block

        instance = new Singleton();
    }
    return instance;
}

Singleton::Singleton()
{
    //initializing...

}


 However, if Singleton::getInstance() is accessed by multiple threads simultaneously, maybe one thread is interrupted just after it passes the check statement, then another thread could enter the object production block too, so the object may be created twice or more times. In this case, there would be more than one object instances in our system, which obeys the idea of singleton factory. To keep the object production block as a crucial area, we could introduce a mutex. Like this:

//v2:

Singleton* Singleton::getInstance()

{

    lock(mutex); //the implemntation of mutex and releated operations vary on differnt platforms.

    if(NULL == instance) //check statement

    {

        //object production block

        instance = new Singleton();

    }

    release(mutex);
    return instance;
}


Now it seems safe enough to ensure only one thread could enter the object production block. It's ture. But the performance issue comes out as a pair of mutex lock and realease operations needs to be executed every time Singleton::getInstance() is called. In fact, after the first call, the instance won't be NULL. So the cost is really very expensive. Don't worry, double-check is designed to solve this problem very well.

 

//v3:


Singleton* Singleton::getInstance()

{

     if(NULL == instance)

     {

        //After the creation of the object once, no thread would enter this block any more, thus the performance is as good as v1 and the secuity is as good as v2.


        //perfect, isn't it.


        lock(mutex);

        if(NULL == instance) //check statement


        {

            //object production block


            instance = new Singleton();

        }

        release(mutex);

     }

    return instance;

}


阅读(193) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~