单例模式
1.确保一个类最多有一个实例
2.代码
C++
(1)懒汉模式:优点 延迟实例化
1 //Singleton c++ 2 //VS2013 编译通过,MinGW 更新至9.2.0-1 <mutex>仍报错, 3 //网站在线编译 https://zh.cppreference.com/w/cpp/thread/mutex 4 #include <iostream> 5 #include <mutex> 6 #include <map> 7 #include <string> 8 #include <thread> 9 #include <iterator> 10 11 using namespace std; 12 13 int g_count = 0; 14 15 class Singleton{ 16 public: 17 static Singleton* getInstance(){ 18 Singleton* result = nullptr; //1.防止A线程尚未完全构造完毕,但此时非null,返回未完全初始化对象,崩溃 19 if (NULL == m_pSingleton){ //2.double check 防止每一次调用都执行lock,影响速度 20 lock_guard<mutex> lock(s_mutex); //3.线程安全,防止还是null时有其他线程进入,效率有损失 21 if (NULL == m_pSingleton){ 22 result = new Singleton(); 23 m_pSingleton = result; //4.构造完毕 24 } 25 } 26 return m_pSingleton; 27 } 28 29 void doSomething(const string& args); 30 31 template<typename It> 32 void printInsertPages(It it, bool success){ 33 cout << "insert:" << it->first << " " << it->second << (success ? "; success\n" : "; fail\n"); 34 } 35 36 static mutex s_mutex; //在这里编译器并未给分配内存 37 map<int, std::string> m_pages; 38 39 private: 40 Singleton() = default; 41 static Singleton* m_pSingleton; 42 }; 43 44 void Singleton::doSomething(const string& args){ 45 auto ret = m_pages.insert({ g_count++, args }); //m_pages[g_count++] = args; ret类型: std::pair<map<int, std::string>::iterator, bool> 46 printInsertPages(ret.first, ret.second); 47 } 48 49 //静态成员初始化,否连接错误 50 Singleton* Singleton::m_pSingleton = nullptr; 51 mutex Singleton::s_mutex; 52 53 //模拟下载 54 void download(const string &url) 55 { 56 Singleton* single = Singleton::getInstance(); 57 lock_guard<mutex> lock(Singleton::s_mutex); //确保map插入正确,无将乱序 58 std::this_thread::sleep_for(std::chrono::seconds(1)); 59 single->doSomething(url); 60 } 61 62 63 int main() 64 { 65 thread t1(download,"http://AAA"); 66 thread t2(download,"http://BBB"); 67 t1.join(); 68 t2.join(); //”join”等待线程返回后再终结 69 70 // 71 Singleton* single = Singleton::getInstance(); 72 for (const auto &pair : single->m_pages) { 73 std::cout << pair.first << " => " << pair.second << '\n'; 74 } 75 return 0; 76 }
(2)饿汉模式
1 //Singleton c++ 2 //饿汉模式,线程安全,在进入main函数之前就由单线程方式实例化的 3 #include <iostream> 4 using namespace std; 5 6 class Singleton{ 7 public: 8 static Singleton* getInstance(){ return m_pSingleton; } 9 private: 10 Singleton()=default; 11 static Singleton* m_pSingleton; 12 }; 13 14 Singleton* Singleton::m_pSingleton = new Singleton(); 15 16 int main(){ 17 auto p1 = Singleton::getInstance(); 18 auto p2 = Singleton::getInstance(); 19 20 if(p1 == p2) 21 cout<<"same, "<<p1; 22 23 return 0; 24 }
Java
1 //Singleton java 2 class Singleton{ 3 private volatile static Singleton uniqueInstance; 4 private Singleton(){} 5 public static Singleton getInstance(){ 6 if(null == uniqueInstance){ 7 synchronized(Singleton.class){ //synchronized 8 if(null == uniqueInstance) 9 uniqueInstance = new Singleton(); 10 count++; 11 } 12 } 13 return uniqueInstance; 14 } 15 public static int count = 0; //need static 16 } 17 18 public class SingleClient{ 19 public static void main(String[] args){ 20 Singleton single_1 = Singleton.getInstance(); 21 Singleton single_2 = Singleton.getInstance(); 22 System.out.println("1:" + single_1 + " count:" + single_1.count); 23 System.out.println("2:" + single_2 + " count:" + single_2.count); 24 } 25 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通