顾名思义,单例模式是用来保证这个类在运行期间只会被创建一个类实例,另外,单例模式还提供了一个全局唯一访问这个类实例的访问点,就是getInstance方法1。
下面看看该类的实现
首先看看标准教科书式的单例模式
头文件:
//
// Singleton.h
// DesignPattern
//
// Created by NULL on 3/22/16.
// Copyright © 2016 NCL. All rights reserved.
//
#ifndef Singleton_h
#define Singleton_h
#include <stdio.h>
class Singleton
{
private:
static Singleton * m_instance;
Singleton();
~Singleton();
public:
static Singleton * getInstance();
};
#endif /* Singleton_hpp */
cpp:
//
// Singleton.cpp
// DesignPattern
//
// Created by NULL on 3/22/16.
// Copyright © 2016 NCL. All rights reserved.
//
#include "Singleton.h"
Singleton* Singleton::getInstance()
{
if ( NULL == m_instance )
{
m_instance = new Singleton;
}
return m_instance;
}
Singleton* Singleton::m_instance = NULL;
然而这个单例模式就线程安全了吗?答案是否定的。当m_instance == NULL(对象还未被实例化的时候),此时A线程调用Singleton::getInstance(),当A线程跑完if()判断条件后,正要进行m_instance = new Singleton;的时候,CPU时间片耗完了,于是B线程此时又来调用getInstance()方法,当B线程实例化完成了Singleton之后,时间片又回到了A线程,此时A线程又会实例化一个Singleton,这就会造成内存泄露。
那么,线程安全的单例模式怎么写?需要用到线程同步吗?用到线程同步当然可以!但是还有更好的方法。
.h:
//
// Singleton_Thread_Safe.h
// DesignPattern
//
// Created by NULL on 3/22/16.
// Copyright © 2016 NCL. All rights reserved.
//
#ifndef Singleton_Thread_Safe_h
#define Singleton_Thread_Safe_h
#include <stdio.h>
class Singleton_Thread_Safe
{
private:
static Singleton_Thread_Safe * m_instance;
Singleton_Thread_Safe();
~Singleton_Thread_Safe();
public:
static Singleton_Thread_Safe * getInstance();
};
#endif /* Singleton_Thread_Safe_hpp */
.cpp:
//
// Singleton_Thread_Safe.cpp
// DesignPattern
//
// Created by NULL on 3/22/16.
// Copyright © 2016 NCL. All rights reserved.
//
#include "Singleton_Thread_Safe.h"
Singleton_Thread_Safe* Singleton_Thread_Safe::getInstance()
{
return m_instance;
}
Singleton_Thread_Safe* Singleton_Thread_Safe::m_instance = new Singleton_Thread_Safe;
因为静态的变量在程序开始时最先被初始化,因此这样的单例模式不存在线程安全的问题,也省去了每次调用getInstance()的时候都要判断m_instance是否为空。
- 陈臣 (2011-01-01). 研磨设计模式 (Kindle Locations 1677-1679). 清华大学出版社. Kindle Edition. ↩