当前位置: 首页 > news >正文

单例模式(懒汉模式、饿汉模式)

单例模式要解决的问题

主要用于解决一个全局使用的类频发的创建和销毁的问题。单例模式下确保某一个类中只有一个实例,并且自行实例化,然后自行提供给整个系统使用。

单例的实现步骤

1、将该类的构造方法定义为私有方法。这样其他程序就无法通过调用该类的构造方法来实例化该类的对象,只能通过类提供的静态方法,得到该类的唯一实例;

2、在该类中提供一个静态方法。当调用这个方法时,如果存在实例,就返回这里实例。如果不存在,就创建这个实例,并返回。

代码实现

1、懒汉模式(线程不安全)

// 经典懒汉模式(用时再创建)
class Singleton // 线程不安全
{
public:
	static Singleton* getInstance() 
	{
		if (instance == NULL)
		{
			instance = new Singleton();
		}
		return instance;
	}
protected:
	Singleton() { cout << "Singleton()" << endl; }
private:
	static Singleton* instance;
};

Singleton* Singleton::instance = nullptr;

在多线程中,可能存在多个线程同时进入,并创建多个实例的情况。因此需要使用锁来确保线程安全。

2、线程安全的懒汉模式

class Singleton2 // 懒汉模式(线程安全)
{
public:
	static Singleton2* getInstance()
	{  // 双重锁机制
		if (instance == NULL)
		{ // 若不为空,说明已经存在实例,为空,则进入后加锁
			mutex.lock();
			if (instance == NULL)
			{ // 再次判断,确保只有一个线程进入
				instance = new Singleton2(); //创建实例
			}
			mutex.unlock(); //解锁
		}
		return instance;
	}
protected:
	Singleton2() { cout << "Singleton2()" << endl; }
private:
	static Singleton2* instance;
	static std::mutex mutex;
};

Singleton2* Singleton2::instance = NULL;
mutex Singleton2::mutex;

通过双重锁就可以确保只存在一个实例。

3、恶汉模式

class Singleton1  // 饿汉模式,基于类加载实现单例(不管用不用,先创建出来)
{
public:
	static Singleton1* getInstance()
	{
		return instance;
	}
protected:
	Singleton1() { cout << "Singleton1()" << endl; }
private:
	static Singleton1* instance;
}; 

// 必须类外初始化,在类加载时就执行,可能产生垃圾对象
Singleton1* Singleton1::instance = new Singleton1();

恶汉模式,本身就是线程安全的,其基于类加载确保实现单例。

 

相关文章:

  • 工厂模式抽象工厂
  • 链表翻转
  • LRU缓存算法
  • 判断单链表中是否存在环
  • LeeCode61 旋转链表
  • LeeCode74 搜索二维矩阵
  • (0)Nginx 功能特性
  • (2)nginx 安装、启停
  • (3)nginx 配置(nginx.conf)
  • 汇编语言学习笔记--基础知识篇
  • IAR for 430软件的简单使用
  • 430单片机时钟系统与复位系统的配置(1)
  • 430单片机时钟系统与复位系统的配置(2)
  • STM32F103芯片的一些小知识
  • RCC的一些小知识
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • Android Volley源码解析
  • Java Agent 学习笔记
  • javascript 哈希表
  • java小心机(3)| 浅析finalize()
  • Laravel 菜鸟晋级之路
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • React Native移动开发实战-3-实现页面间的数据传递
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • Swoft 源码剖析 - 代码自动更新机制
  • 从零搭建Koa2 Server
  • 动态魔术使用DBMS_SQL
  • 蓝海存储开关机注意事项总结
  • 聊聊flink的TableFactory
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 模型微调
  • 前端面试题总结
  • 前嗅ForeSpider采集配置界面介绍
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • ​iOS实时查看App运行日志
  • #Z2294. 打印树的直径
  • (0)Nginx 功能特性
  • (3)llvm ir转换过程
  • (HAL库版)freeRTOS移植STMF103
  • (第27天)Oracle 数据泵转换分区表
  • (第二周)效能测试
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)socket Aio demo
  • **python多态
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET MVC第三章、三种传值方式
  • .NET Remoting学习笔记(三)信道
  • .NET 读取 JSON格式的数据
  • .NET多线程执行函数
  • @GlobalLock注解作用与原理解析
  • @RestControllerAdvice异常统一处理类失效原因