欢迎访问 生活随笔!

ag凯发k8国际

当前位置: ag凯发k8国际 > 编程语言 > asp.net >内容正文

asp.net

设计模式的理解:单例模式(singleton) -ag凯发k8国际

发布时间:2024/10/14 asp.net 26 豆豆
ag凯发k8国际 收集整理的这篇文章主要介绍了 设计模式的理解:单例模式(singleton) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

单例模式使用的目的是 ①一个类只能初始化出一个对象 ②保证对象是线程安全的。

其做法:

1、将 构造函数 和拷贝构造函数 设置为私有 并将自身类的指针设置成静态成员,其函数方法也设置成静态方法。保证该类只创建一个对象

2、通过加锁的方式,对 对象访问加以限制

class singleton { private:static singleton * instance; singleton (){} singleton(const singleton& other);public:static singleton* getinstance() { if (instance == nullptr) { instance = new singleton(); } return instance; } }

以上在单线程中是可以满足一个类对象只会被初始化一次的条件。但是在多线程中 假如其中一个线程在执行   instance = new singleton();   语句前,而另外一个刚好进入 if 语句时,这个类就会被初始化两次。所以上述的编码方式时线程不安全的。

二、双重加锁

class singleton { private:static singleton * instance; singleton (){} singleton(const singleton& other);public:static singleton* getinstance() { if (instance == nullptr) { lock lock;if(instance == nullptr){instance = new singleton(); }} return instance; } }

上述代码是双重锁机制,当一个线程先获取到锁的时候,第二个线程读锁时就会等待第一个锁初始化完对象后才继续执行。但是上述写法没有考虑到内存读写reorder不安全。

正常创建对象实例会走三步骤

1) 分配对象内存

2) 调用构造器,执行初始化

3) 将对象的引用赋值给变量。

然而在编译器优化等问题下,在实际可能的运行顺序是,先执行第三步再执行第二部,即先引用给对象再调用构造器。

如果

假如其中一个线程在执行   instance = new singleton();   语句时,分配完了内存,将对象将对象的引用赋值给变量,此时第二个线程判断 if (instance == nullptr) 不成立直接返回了一个还未初始化完的对象。那么就会造成线程不安全。这个创建对象的二三步骤乱序执行实际上叫重排序。

在java ,c#中 ,新增了一个关键字volatile,在声明成员变量时  volatile static singleton instance;    表示禁止 instance创建对象时重排序。

而在c 11版本的跨平台实现

//c 11版本之后的跨平台实现 // atomic c 11中提供的原子操作 std::atomic singleton::m_instance; std::mutex singleton::m_mutex;/* * std::atomic_thread_fence(std::memory_order_acquire); * std::atomic_thread_fence(std::memory_order_release); * 这两句话可以保证他们之间的语句不会发生乱序执行。 */ singleton* singleton::getinstance() {singleton* tmp = m_instance.load(std::memory_order_relaxed);std::atomic_thread_fence(std::memory_order_acquire);//获取内存fenceif (tmp == nullptr) {std::lock_guard lock(m_mutex);tmp = m_instance.load(std::memory_order_relaxed);if (tmp == nullptr) {tmp = new singleton;std::atomic_thread_fence(std::memory_order_release);//释放内存fencem_instance.store(tmp, std::memory_order_relaxed);}}return tmp; }

 

或者有更简洁的c 写法,但在c 11版本前不支持。

class singleton{ public:// 注意返回的是引用。static singleton& getinstance(){static singleton m_instance; //局部静态变量return m_instance;} private:singleton(); //私有构造函数,不允许使用者自己生成对象singleton(const singleton& other); };

 

 

 

 

 

 

总结

以上是ag凯发k8国际为你收集整理的设计模式的理解:单例模式(singleton)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得ag凯发k8国际网站内容还不错,欢迎将ag凯发k8国际推荐给好友。

网站地图