We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
原文地址(更好的阅读体验): 📖
保证一个类只有一个实例,并提供一个该实例的全局访问点
类的定义
class Singleton{ private: Singleton(); Singleton(const Singleton& other); public: static Singleton* getInstance(); static Singleton* m_instance; }; Singleton* Singleton::m_instance=nullptr;
线程非安全版本
Singleton* Singleton::getInstance() { 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; }
双检查锁,由于内存读写指令重排序不安全
在 m_instance = new Singleton()中,指令流分为三部分
m_instance = new Singleton()
1.分配内存
2.调用构造器,将内存初始化
3.将内存地址赋值给 m_instance
但是在 CPU 级别,可能有指令重排序,可能顺序为
2.将内存地址赋值给 m_instance
3.调用构造器,初始化内存
在重排序的顺序中,如果 TreadA 执行到了 m_instance = new Singleton()的第二步骤
此时 m_instance 不为 nullptr
m_instance
nullptr
如果此时有另一个线程执行了 if(m_instance==nullptr) 此判断,则认为m_instance可以使用,其实不能使用
if(m_instance==nullptr)
Singleton* Singleton::getInstance() { if(m_instance==nullptr){ Lock lock; if (m_instance == nullptr) { m_instance = new Singleton(); } } return m_instance; }
public final class Singleton { // The field must be declared volatile so that double check lock would work // correctly. // 必须使用 volatile 关键字修饰来避免指令重排序 private static volatile Singleton instance; public String value; private Singleton(String value) { this.value = value; } public static Singleton getInstance(String value) { if(instance == null){ synchronized(Singleton.class) { if (instance == null) { instance = new Singleton(value); } } } return instance; } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
单例模式
原文地址(更好的阅读体验): 📖
动机
定义
保证一个类只有一个实例,并提供一个该实例的全局访问点
代码实现
类的定义
线程非安全版本
线程安全 但是锁代价过高的版本
双检查锁,由于内存读写指令重排序不安全
在
m_instance = new Singleton()
中,指令流分为三部分1.分配内存
2.调用构造器,将内存初始化
3.将内存地址赋值给 m_instance
但是在 CPU 级别,可能有指令重排序,可能顺序为
1.分配内存
2.将内存地址赋值给 m_instance
3.调用构造器,初始化内存
在重排序的顺序中,如果 TreadA 执行到了
m_instance = new Singleton()
的第二步骤此时
m_instance
不为nullptr
如果此时有另一个线程执行了
if(m_instance==nullptr)
此判断,则认为m_instance
可以使用,其实不能使用The text was updated successfully, but these errors were encountered: