单例模式 发表于 2022-03-08 | 分类于 设计模式 , 单例模式 | 单例模式 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152#include<iostream>using namespace std;//实现单例步骤//1.构造函数私有化//2.增加静态私有的当前类的指针变量//3.提供静态对外公共接口,获得单例对象//单例 分为懒汉式 饿汉式//1.懒汉式(需要的时候才会创建)class Single_lazy {private: //静态锁,是由于静态函数只能访问静态成员 static pthread_mutex_t lock; //私有化构造函数 Single_lazy() { pthread_mutex_init(&lock, NULL); } //当前类的私有静态指针变量指向唯一实例 static Single_lazy *p; ~Single_lazy(){} public: //公有静态方法获取实例 static Single_lazy* getInstance();};pthread_mutex_t single::lock;//类外初始化Single_lazy* Single_lazy::p = NULL;Single_lazy* Single_lazy::getInstance(){ if(p == NULL){ pthread_mutex_lock(&lock); if(p == NULL){ p = new Single_lazy; } pthread_mutex_unlock(&lock); } return p;}//为什么要用双检测,只检测一次不行吗?//如果只检测一次,在每次调用获取实例的方法时,都需要加锁,//这将严重影响程序性能。双层检测可以有效避免这种情况,//仅在第一次创建单例的时候加锁,//其他时候都不再符合NULL==p的情况,//直接返回已创建好的实例。 1234567891011121314151617181920212223242526272829303132333435package mainimport ( "fmt" "sync")//实现单例步骤//1.构造函数私有化//2.增加静态私有的当前类的指针变量//3.提供静态对外公共接口,获得单例对象//单例 分为懒汉式 饿汉式//1.懒汉式(需要的时候才会创建)type SingleLazy struct {}var ( instanceLazy *SingleLazy onceLazy sync.Once)//公有静态方法获取实例func GetInstanceLazy() *SingleLazy { onceLazy.Do(func() { instanceLazy = &SingleLazy{} }) return instanceLazy}//sync.Once内部使用了双重检查锁定模式,//保证了线程安全且只初始化一次。//Do方法只会在第一次调用时执行传入的函数,//之后的调用都会直接返回,不会重复执行。 1234567891011121314//局部静态变量之线程安全懒汉模式class Single_lazy{private: Single_lazy() {} ~Single_lazy() {}public: static Single_lazy* getInstance();}Single_lazy* Single_lazy::getInstance(){ static Single_lazy obj; return &obj;} 123456789101112131415//局部静态变量之线程安全懒汉模式type SingleLazyStatic struct {}var ( instanceLazyStatic *SingleLazyStatic onceLazyStatic sync.Once)func GetInstanceLazyStatic() *SingleLazyStatic { onceLazyStatic.Do(func() { instanceLazyStatic = &SingleLazyStatic{} }) return instanceLazyStatic} 12345678910111213141516171819202122232425//2.饿汉式class Single_hungry {private: //当前类的私有静态指针变量指向唯一实例 static Single_hungry* p; //私有化构造函数 Single_hungry(){} ~Single_hungry(){} public: static Single_hungry* getInstance();};//类外初始化Single_hungry* Single_hungry::p = new Single_hungry;Single_hungry* Single_hungry::getInstance(){ return p;}//饿汉模式不需要用锁,就可以实现线程安全。//原因在于,在程序运行时就定义了对象,并对其初始化。//之后,不管哪个线程调用成员函数getinstance(),//都只不过是返回一个对象的指针而已。所以是线程安全的,//不需要在获取实例的成员函数中加锁。 123456789101112131415//2.饿汉式type SingleHungry struct {}var instanceHungry *SingleHungry = &SingleHungry{}func GetInstanceHungry() *SingleHungry { return instanceHungry}//饿汉模式不需要用锁,就可以实现线程安全。//原因在于,在程序运行时就定义了对象,并对其初始化。//之后,不管哪个线程调用成员函数getinstance(),//都只不过是返回一个对象的指针而已。所以是线程安全的,//不需要在获取实例的成员函数中加锁。 12345678910111213141516171819202122232425void test01() { Single_lazy* p1 = Single_lazy::getInstance(); Single_lazy* p2 = Single_lazy::getInstance(); if (p1 == p2) { cout << "两个指针指向同一块内存空间,是单例!" << endl; } else { cout << "不是单例模式!" << endl; } Single_hungry* p3 = Single_hungry::getInstance(); Single_hungry* p4 = Single_hungry::getInstance(); if (p3 == p4) { cout << "两个指针指向同一块内存空间,是单例!" << endl; } else { cout << "不是单例模式!" << endl; }}int main() { test(); return 0;} 123456789101112131415161718192021func test01() { p1 := GetInstanceLazy() p2 := GetInstanceLazy() if p1 == p2 { fmt.Println("两个指针指向同一块内存空间,是单例!") } else { fmt.Println("不是单例模式!") } p3 := GetInstanceHungry() p4 := GetInstanceHungry() if p3 == p4 { fmt.Println("两个指针指向同一块内存空间,是单例!") } else { fmt.Println("不是单例模式!") }}func main() { test01()} -------------本文结束 感谢阅读------------- 本文作者: HReina 本文链接: http://hreina.com/2022/03/08/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/ 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!