大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
动机
在软件系统中,经常有一些特殊的类,必须保证它们在系统中只存在一个实例,才能保证他们的逻辑正确性、以及良好的效率
如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?
模式定义
保证一个类仅有一个实例,并提供一个该实例的全局访问点。
实例
单例
class Singleton{
private :
Singleton();
Singleton(const Singleton& other);
public:
static Singleton* getInstacne();
static Singleton* m_instance;
}
Singleton* Singleton::m_instance = nullptr;
//线程非安全
Singleton* Singleton::getInstacne(){
if(m_instance == nullptr){
m_instance = new Singleton();
}
return m_instance;
}
//线程安全
Singleton Singleton::getInstance(){
Lock lock;
if(m_instance == nullptr){
m_instance = new Singleton();
}
return m_instance;
}
//双检测锁,但由于内存读写recorder不安全
Singleton* Singleton::getInstacne(){
if(m_instance == nullptr){
Lock lock;
if(m_instance == nullptr){
m_instance = new Singleton();
}
}
return m_instance;
}
//C++11版本之后的跨平台实现(voliate)
std::atomic<Singleton*>Singleton::m_instance;
std::mutex Singleton::m_mutex;
Singleton* Singleton::getInstance(){
Singleton* tmp = m_instance.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);//获取内存fence
if(tmp == nullptr){
std::lock_guard<std::mutex> lock(m_mutex);
tmp = m_instance.load(std::memory_order_relaxed);
if(tmp == nullptr){
tmp = new Singleton();
std::atomic_thread_fence(std::memory_order_release);//释放内存fence
m_instance.store(tmp,std::memory_order_relaxed);
}
}
return tmp;
}
结构
要点总结
- Singleton 模式中的实例构造器可以设置为protected以允许子类派生。
- Singleton 模式一般不要支持拷贝构造函数和Clone接口,因为这有可能导致多个对象实例,与Singleton模式的初衷相违背
- 如何实现多线程环境下安全的Singleton?注意对双检查锁的正确实现
笔记
- 保证只有一个单例是设计者的责任 不是使用者的责任
- java C#都有voliate机制
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/169039.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...