c++的单例模式与线程安全单例模式(懒汉/饿汉)

author author     2022-08-03     628

关键词:

1 教科书里的单例模式

  我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的动作由一个public的类方法代劳,该方法也返回单例类唯一的实例。

  上代码:  

class singleton
{
protected:
	singleton(){}
private:
	static singleton* p;
public:
	static singleton* instance();
};
singleton* singleton::p = NULL;
singleton* singleton::instance()
{
	if (p == NULL)
		p = new singleton();
	return p;
}

  这是一个很棒的实现,简单易懂。但这是一个完美的实现吗?不!该方法是线程不安全的,考虑两个线程同时首次调用instance方法且同时检测到p是NULL值,则两个线程会同时构造一个实例给p,这是严重的错误!同时,这也不是单例的唯一实现!

2 懒汉与饿汉

  单例大约有两种实现方法:懒汉与饿汉。

    • 懒汉:故名思义,不到万不得已就不会去实例化类,也就是说在第一次用到类实例的时候才会去实例化,所以上边的经典方法被归为懒汉实现;
    • 饿汉:饿了肯定要饥不择食。所以在单例类定义的时候就进行实例化。

  特点与选择:

    • 由于要进行线程同步,所以在访问量比较大,或者可能访问的线程比较多时,采用饿汉实现,可以实现更好的性能。这是以空间换时间。
    • 在访问量较小时,采用懒汉实现。这是以时间换空间。

3 线程安全的懒汉实现

  线程不安全,怎么办呢?最直观的方法:加锁。

  • 方法1:加锁的经典懒汉实现:

class singleton
{
protected:
	singleton()
	{
		pthread_mutex_init(&mutex);
	}	
private:
	static singleton* p;
public:
	pthread_mutex_t mutex;
	static singleton* initance();
};
singleton* singleton::p = NULL;
singleton* singleton::initance()
{
	if (p == NULL)
	{
		pthread_mutex_lock(&mutex);
		if (p==NULL)
			p = new singleton();
		pthread_mutex_unlock(&mutex);
	}
	return p;
}
  • 方法2:内部静态变量的懒汉实现

  此方法也很容易实现,在instance函数里定义一个静态的实例,也可以保证拥有唯一实例,在返回时只需要返回其指针就可以了。推荐这种实现方法,真得非常简单。    

class singleton
{
protected:
	singleton()
	{
		pthread_mutex_init(&mutex);
	}
public:
	pthread_mutex_t mutex;
	static singleton* initance();
	int a;
};

singleton* singleton::initance()
{
	pthread_mutex_lock(&mutex);
	static singleton obj;
	pthread_mutex_unlock(&mutex);
	return &obj;
}

4 饿汉实现

  为什么我不讲“线程安全的饿汉实现”?因为饿汉实现本来就是线程安全的,不用加锁。为啥?自己想!

class singleton
{
protected:
	singleton()
	{}
private:
	static singleton* p;
public:
	static singleton* initance();
};
singleton* singleton::p = new singleton;
singleton* singleton::initance()
{
	return p;
}

  是不是特别简单呢?

  以空间换时间,你说简单不简单?

  面试的时候,线程安全的单例模式怎么写?肯定怎么简单怎么写呀!饿汉模式反而最懒[正经脸]! 

单例模式的懒汉模式与饿汉模式之间的对比c++(代码片段)

  单例模式,是GOF23种设计模式中的一种,有2种方法可以实现单例模式,分为懒汉式、饿汉式,它们的区别如下:对比懒汉式单例饿汉式单例创建时间需要时才创建,在程序运行之后调用getInstance()创建... 查看详情

彻头彻尾理解单例模式与多线程

...我们特别介绍了五种方式来在多线程环境下创建线程安全的单例,使用synchronized方法、synchronized块、静态内部类、双重检查模式和ThreadLocal实现懒汉式单例,并 查看详情

线程安全的单实例模式

我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个privatestatic的类指针保存唯一的实例,实例的动作由一个public的类方法代劳,该方法也返回单例类唯一的实例。... 查看详情

什么是单例模式?

...时候,才去创建对象相关经验:饿汉式(是不会出现问题的单例模式)懒汉式(可能会出现问题的单例模式)(1.)懒加载(延迟加载)(2.)线程安全问题1.)是否多线程环境是2.)是否有共享数据是3.)是否有多条语句操作共... 查看详情

设计模式之单例模式

C++的单例模式与线程安全的单例模式(懒汉/饿汉)1教科书里的单例模式  我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个privatestatic的类指针保存唯一的实例... 查看详情

c++单例模式的实现(懒汉式饿汉式)(代码片段)

单例模式-Singleton名词解释动机要点饿汉式实现方式运行结果懒汉式常规实现线程安全版实现精简实现参考资料名词解释数学与逻辑学中,singleton定义为:有且仅有一个元素的集合。单例模式最初的定义出现在《设计模式... 查看详情

单例模式(饿汉模式和懒汉模式)(代码片段)

饿汉模式饿汉模式是线程安全的,不需要关键字来保证线程安全。classSingleton//期望singleton是一个单例,也就是只有一个实例privatestaticfinalSingletoninstance=newSingleton();publicstaticSingletongetInstance()returninstance;privateSingleto 查看详情

单例模式的线程安全性

...象访问,因此需要一个全局的访问指针,这便是众所周知的单例模式的应用。经典的单例模式有三种,懒汉式、饿汉式和懒汉式单例模式改进式“懒汉式”是在你真正用到的时候才去建这个单例对象,所以是线程不安全的懒汉式... 查看详情

多线程与单例模式

学过单例都知道饿汉式和懒汉式单例中饿汉式如果存在静态变量时在引用此变量时将会一并创建对象,这会导致线程的不安全!懒汉式看看:懒汉式采用synchronized来解决线程安全问题,但是synchronized又会导致阻塞性问题,效率会... 查看详情

java之单例设计模式

/*1.单例设计模式:所谓的单例设计模式:就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例2.如何实现1.饿汉式2.懒汉式3.如何区分饿汉式:坏处:对象加载时间过长好处:饿汉式是线程安全的懒汉式... 查看详情

java基础——线程安全的单例模式懒汉式

packagesavesingleton;/*使用同步将单例模式中的懒汉式改写成线程安全的@authorzsben@create2020-01-0322:22*/classBank{privateBank(){}privatestaticBankinstance=null;/*publicstaticsynchronizedBankgetInstance(){if(instance==null){ 查看详情

线程安全的懒汉式单例设计模式

首先回顾一下单利设计模式:   单利设计模式是通过某种方式使某个类只能创建一个对象实例供外界使用。单利设计模式分为懒汉式和饿汉式:饿汉式是线程安全的: 1//饿汉式单利设计模式:2classSingle{3privatestaticfi... 查看详情

单例模式

单例模式有懒汉和饿汉两种形式:懒汉不占用内存,但是不是线程安全的,所以要加锁保证线程安全。饿汉开始就创建好了,所以会一直占用内存,但是它是线程安全的。各有各的好,考虑具体需求使用classLazy//懒汉式,先不创... 查看详情

单例模式:饿汉式与懒汉式

单例模式唯一的实例注意:私有化构造器、自行创建(含有一个该类的静态变量来保存唯一实例)、必须自行向整个系统提供这个实例(对外提供获取该实例对象的方式:1、直接暴露2、静态变量的get方法获取)几种常见形式饿... 查看详情

如何写一个简单的单例模式?

如何写一个简单的单例模式?一、基本的实现思路:单例的实现主要是通过以下两个步骤:1、将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象,只有通过该类提供的静态... 查看详情

单例模式(饿汉方式懒汉方式)(代码片段)

单例模式1.饿汉方式(线程安全的)(1)代码实现(2)饿汉方式的优缺点优点缺点2.懒汉方式(1)代码实现①懒汉实现版本一(非线程安全的)②版本二:可以保证线程安全,锁粒... 查看详情

单利模式(饿汉模式,懒汉模式)线程安全与解决问题

 单例模式1.饿汉模式:在类被加载的时候创建实例(线程安全的)2.懒汉模式:在方法被运行的时候创建实例(线程不安全的)解决方法:通过双检验饿汉模式:publicclassSingleton{//饿汉模式//将构造函数私有化privateSingleton(){}//... 查看详情

java学习日记20230323-单例设计模式

...代码结构,编程风格,以及解决问题的思考方式。所谓类的单例设计模式,就是采用一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得对象实例的方法饿汉式:可能造成资源浪费,对... 查看详情