单例模式

Posted sansuiwantong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式相关的知识,希望对你有一定的参考价值。

1.确保一个类最多有一个实例

2.代码

C++

 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
" : "; fail
");
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();    
69     
70     //
71     Singleton* single = Singleton::getInstance();
72     for (const auto &pair : single->m_pages) {
73         std::cout << pair.first << " => " << pair.second << 
;
74     }
75     return 0;
76 }

技术图片

 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 }

技术图片

 

以上是关于单例模式的主要内容,如果未能解决你的问题,请参考以下文章

常用代码片段

性能比较好的单例写法

片段作为 Android 中的单例

单例片段或保存网页视图状态

你熟悉的设计模式都有哪些?写出单例模式的实现代码

单例模式以及静态代码块