单例模式

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 }

 

posted @ 2020-04-12 03:36  三岁玩童  阅读(189)  评论(0编辑  收藏  举报