转 一种线程安全的单例模式
2010-09-20 15:57
281 查看
一种线程安全的单例模式
#include <memory>
// 同步对象
class Mutex
{
public:
Mutex()
{
cout << "initial mutex" << endl;
}
~Mutex()
{
cout << "uninitial mutex" << endl;
}
void lock()
{
cout << "lock" << endl;
}
void unlock()
{
cout << "unlock" << endl;
}
};
// 同步资源管理对象
class Guard
{
public:
Guard(Mutex& mtx):
m_mtx(mtx)
{
m_mtx.lock();
}
~Guard()
{
m_mtx.unlock();
}
private:
Mutex &m_mtx;
};
// 辅助类; 针对每一个会使用的类型都提供一个锁, 这个锁在进入main之前由主线程创建,
// 最后也由主线程销毁; 创建和销毁绝无线程竞争
template<typename T>
struct SingletonHelper
{
static Mutex cs_mtx;
};
template<typename T>
Mutex SingletonHelper<T>::cs_mtx;
// 针对每一个类提供一个单例访问点; 如果从不访问, 则不会创建多余对象
template<typename T>
T& getInstance()
{
// 智能指针, 保证能够在程序退出时销毁对象, 确保释放跨进程资源
// 由主线程销毁, 绝对安全
// 创建对象时因为可能是多线程同时访问getInstance造成, 所以存在竞争, 由后面的代码解决
static std::auto_ptr<T> ls_object;
// 后期getInstance调用ls_object.get()非空, 最初可能为空
if (ls_object.get() == NULL)
{
// 由于这个锁, 进入这里的多线程会被限制为轮流进入
Guard grd(SingletonHelper<T>::cs_mtx);
// 第一进入的线程负责创建对象, 后来的线程直接判断为非空
if (ls_object.get() == NULL)
{
// 第一批调用getInstance的线程中, 只有一个能执行这行代码
ls_object.reset(T::createInstance());
}
}
return *ls_object;
}
class Singleton
{
public:
// 公开方法
void method1()
{
cout << "method1 call" << endl;
}
// 为了getInstance能析构
// 因为所有的构造函数已被私有, 所以只要不delete &getInstance();就安全
~Singleton()
{
cout << "last destruct" << endl;
}
private:
// 避免多余的创建
Singleton(int p1, const char *p2)
{
cout << "first construct" << endl;
}
// 禁止拷贝
Singleton& operator = (const Singleton&);
Singleton(const Singleton&);
// 提供给getInstance获取对象
static Singleton* createInstance()
{
return new Singleton('p1', "p2");
}
// 对getInstance放开权限
friend Singleton& getInstance<Singleton>();
};
template<int iIndex>
class Customer
{
public:
Customer(int i, const Singleton&)
{
cout << "customer " << iIndex << '-' << i << " visit" << endl;
}
};
// 全局对象的访问
Customer<0> g_cstm(1, getInstance<Singleton>());
int main()
{
// 全部对象的访问
Customer<1> cstm2(1, getInstance<Singleton>());
getInstance<Singleton>().method1();
Customer<1> cstm3(2, getInstance<Singleton>());
}
//未测试
#include <memory>
// 同步对象
class Mutex
{
public:
Mutex()
{
cout << "initial mutex" << endl;
}
~Mutex()
{
cout << "uninitial mutex" << endl;
}
void lock()
{
cout << "lock" << endl;
}
void unlock()
{
cout << "unlock" << endl;
}
};
// 同步资源管理对象
class Guard
{
public:
Guard(Mutex& mtx):
m_mtx(mtx)
{
m_mtx.lock();
}
~Guard()
{
m_mtx.unlock();
}
private:
Mutex &m_mtx;
};
// 辅助类; 针对每一个会使用的类型都提供一个锁, 这个锁在进入main之前由主线程创建,
// 最后也由主线程销毁; 创建和销毁绝无线程竞争
template<typename T>
struct SingletonHelper
{
static Mutex cs_mtx;
};
template<typename T>
Mutex SingletonHelper<T>::cs_mtx;
// 针对每一个类提供一个单例访问点; 如果从不访问, 则不会创建多余对象
template<typename T>
T& getInstance()
{
// 智能指针, 保证能够在程序退出时销毁对象, 确保释放跨进程资源
// 由主线程销毁, 绝对安全
// 创建对象时因为可能是多线程同时访问getInstance造成, 所以存在竞争, 由后面的代码解决
static std::auto_ptr<T> ls_object;
// 后期getInstance调用ls_object.get()非空, 最初可能为空
if (ls_object.get() == NULL)
{
// 由于这个锁, 进入这里的多线程会被限制为轮流进入
Guard grd(SingletonHelper<T>::cs_mtx);
// 第一进入的线程负责创建对象, 后来的线程直接判断为非空
if (ls_object.get() == NULL)
{
// 第一批调用getInstance的线程中, 只有一个能执行这行代码
ls_object.reset(T::createInstance());
}
}
return *ls_object;
}
class Singleton
{
public:
// 公开方法
void method1()
{
cout << "method1 call" << endl;
}
// 为了getInstance能析构
// 因为所有的构造函数已被私有, 所以只要不delete &getInstance();就安全
~Singleton()
{
cout << "last destruct" << endl;
}
private:
// 避免多余的创建
Singleton(int p1, const char *p2)
{
cout << "first construct" << endl;
}
// 禁止拷贝
Singleton& operator = (const Singleton&);
Singleton(const Singleton&);
// 提供给getInstance获取对象
static Singleton* createInstance()
{
return new Singleton('p1', "p2");
}
// 对getInstance放开权限
friend Singleton& getInstance<Singleton>();
};
template<int iIndex>
class Customer
{
public:
Customer(int i, const Singleton&)
{
cout << "customer " << iIndex << '-' << i << " visit" << endl;
}
};
// 全局对象的访问
Customer<0> g_cstm(1, getInstance<Singleton>());
int main()
{
// 全部对象的访问
Customer<1> cstm2(1, getInstance<Singleton>());
getInstance<Singleton>().method1();
Customer<1> cstm3(2, getInstance<Singleton>());
}
//未测试
相关文章推荐
- 一种线程安全的单例模式(10.4.1更新)
- Lazy方式单列模式,一种线程安全模式的新选择
- 一种线程安全的单例模式实现
- 一种线程安全的单例模式实现
- 单例模式--一种线程安全的写法
- 解决单例设计模式中的懒汉设计模式存在线程安全问题(并且在一定程度上提高效率)的一种解决方法
- C++可微编程:寻找一种最佳的图像抖动模式
- 线程安全 单例模式
- 线程安全的单例模式
- 线程安全的单例模式
- 鸟巢-一种全新的Native APP开发模式,这篇文章为您解读
- 线程安全的单例模式
- 线程安全的单例模式的几种实现方法分享
- 单例模式的一种应用场景
- 一种新的Web用户行为模式挖掘算法的研究(转)
- Windows下的PHP开发环境搭建——PHP线程安全与非线程安全、Apache版本选择,及详解五种运行模式。
- 线程安全的单例模式
- 一种互联网应用的分布式架构模式微服务应用框架的实现(gradle,dubbo,zookeeper,springmmvc)
- 单例模式-静态内部类的实现(线程安全)
- Spring单例模式与线程安全