设计模式——单例模式

来源:互联网 发布:淘宝购物一般几天到货 编辑:程序博客网 时间:2024/06/16 06:10

你肯定被面过这样一个问题:C++中如何实现一个类只能实例化一个对象?

单例模式可以保证一个类只能实例化一个对象!单例模式的核心结构中只包含一个被称为单例的特殊类

防止用户随意的调用构造函数,将类的构造函数写成私有的,给用户提供返回对象的方法,在调用时不能依赖对象。

  • 版本一: 懒加载(不论是否使用,都要初始化)
class Singleton{public:    static Singleton& getInstance()    {        return singlenton;    }private:    Singleton() {};    static Singleton singlenton;};Singleton Singleton::singlenton = Singleton::getInstace() ;//不论是否使用,程序运行后,对象已存在
  • 版本二:快加载(使用时候才初始化)
class Singleton{public:    static Singleton* getInstance()    {        if(psingleTon == NULL)        {            psingleTon = new Singleton();        }        return psingleTon;    }private:    Singleton(){}    static Singleton *psingleTon;};Singleton* Singleton::psingleTon = NULL;/快加载int main(){    //需要时调用getInstance方法new对象    psingleTon *p1 = Singleton::getInstance();}   
  • 版本三:考虑多线程安全问题,使用互斥锁同步

判断是否是线程安全的——是否存在竟态条件(存在竟态条件,非线程安全的)

判断是否存在竟态条件——随着线程调度顺序不同,程序结果是否相同(不相同,存在竟态条件)

存在竟态条件的代码区称为临界区

临界区的代码必须是原子操作

实现原子操作要使用互斥锁

class Singleton{public:    static Singleton* getInstance()    {        //保证多线程下,new对象是原子操作        pthread_mutex_lock(&mutex);        if(psingleTon == NULL)        {            psingleTon = new Singleton();        }        pthread_mutex_unlock(&mutex);        return psingleTon;    }private:    Singleton(){}    static Singleton *psingleTon;};Singleton* Singleton::psingleTon = NULL;//快加载int main(){    Singleton *p1 = Singleton::getInstance();    Singleton *p2 = Singleton::getInstance();//不new    Singleton *p3 = Singleton::getInstance();//不new}
  • 版本四:存在单线程和多线程两种情况,解决单线程加锁解锁的效率问题,使用双重if判断

单线程时,只执行一次加锁加锁的情况,其他第一个if语句都为false,直接return
多线程时,依然考虑线程安全和竟态条件

class Singleton{public:    static Singleton* getInstance()    {        if(NULL == psingleTon)//懒加载        {            pthread_mutex_lock(&mutex);//多线程安全问题            if(NULL == psingleTon)//单线程实现效率问题            {                psingleTon = new Singleton();            }            pthread_mutex_unlock(&mutex);        }        return psingleTon;    }private:    Singleton(){}    static Singleton *psingleTon;};Singleton* Singleton::psingleTon = NULL;int main(){    Singleton *p1 = Singleton::getInstance();//加锁,new    Singleton *p2 = Singleton::getInstance();//直接return     Singleton *p3 = Singleton::getInstance();//直接return }
  • 版本五 考虑编译器的指令优化和CPU的动态指令优化

volatile,阻止编译器为了提高速度,将变量值缓存到寄存器中,
每次直接从寄存器中取数据

volatile,阻止编译器对指令进行动态换序优化

barrier阻止CPU对指令进行动态换序优化

class Singleton{public:    volatile static Singleton* getInstance()    {        if(NULL == psingleTon)//懒加载        {            pthread_mutex_lock(&mutex);//多线程安全问题            if(NULL == psingleTon)//单线程实现效率问题            {                psingleTon = new Singleton();            }            pthread_mutex_unlock(&mutex);        }        return psingleTon;    }private:    Singleton(){}    volatile static Singleton *psingleTon;//防止编译器缓存值};volatile Singleton* Singleton::psingleTon = NULL;int main(){    Singleton *p1 = Singleton::getInstance();//加锁,new    Singleton *p2 = Singleton::getInstance();//直接return     Singleton *p3 = Singleton::getInstance();//直接return }
原创粉丝点击