C++与Java在线程安全的懒汉式单例模式上的差异

对于java而言,可以通过内部类实现单例的延迟加载:

public class Singleton {  
    private Singleton() {};

    private static class SingletonHolder {  
        private static Singleton  instance = new Singleton();  
     }  
      
     public static Singleton getInstance() {  
         return SingletonHolder.instance;  
     }  
}  

由于Java内部类只有在调用到的时候才会加载,并且JVM保证了加载的线程安全,因此这种单例模式是线程安全的。


对于C++而言,没有像JVM这样的类加载机制保证线程安全,因此单例情况比Java要复杂。

如果采用懒汉模式,主要有以下几种方式:

方式1:双重检测及加锁:

class Singleton
{
private:
    static Singleton* m_instance;
    Singleton(){}
public:
    static Singleton* getInstance();
};

in Singleton.cpp:
Singleton* Singleton::getInstance()
{
    if(NULL == m_instance)
    {
        Lock();//借用其它类来实现,如boost
        if(NULL == m_instance)
        {
            m_instance = new Singleton;
        }
        UnLock();
    }
    return m_instance;
}

双重检测也有潜在问题,详情参考文末链接。

方式2:静态内部变量(C++11之前需加锁)

需要注意的是,C++11以后,要求编译器保证内部静态变量的线程安全性,可以不加锁。但C++ 11以前,仍需要加锁。

class Singleton
{
private:
    Singleton(){}
public:
    static Singleton* getInstance();
};
in Singleton.cpp:
Singleton* Singleton::getInstance()
{
    Lock(); // not needed after C++0x
    static Singleton instance;
    UnLock(); // not needed after C++0x
    return &instance; 
}

方式3: 无锁设计:

如果既要懒汉模式,又要无锁设计,针对linux/unix平台, 可以采用pthread_once,例如:

class Singleton { 
public: 
	static Singleton* instance(); 
	static void init() { pIntance = new Singleton; } 
	... 
private: 
	static Singleton* pInstance; 
	static pthread_once_t ponce_; 
}; 

pthread_once_t Singleton::ponce_ = PTHREAD_ONCE_INIT; 

Singleton* Singleton::instance() {
	pthread_once(&ponce_, &Singleton::init); 
	return pInstance; 
}

当然,如果使用饿汉模式,可以避免使用锁:

class Singleton  
{  
public:  
    static Singleton *pInstance;  
    static Singleton *getInstance()  
    {  
        return pInstance;  
    }  
private:  
      
    Singleton(){}  
};

在Singleton.cpp中初始化:  
Singleton * Singleton::pInstance = new Singleton();

参考文献:

http://www.zkt.name/dan-li-mo-shi-singleton-ji-c-shi-xian/

https://www.jianshu.com/p/d9334d992cbe


猜你喜欢

转载自blog.csdn.net/sundongsdu/article/details/79496345
今日推荐