[设计模式] -- 单例模式

article/2025/9/19 2:34:38

Emai : hahayacoder@gmail.com

 

背景

最近在公司的项目中,经常会用到单例模式,由于之前没有想过怎么正确使用单例模式,导致写成的程序中有BUG。在学习Cocos2d-x时,导演类CCDirector等都是单例类。所以从头开始学习单例模式。

 

介绍

单例模式也称为单件模式,单子模式.使用单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有模块共享.有很多地方需要这样的功能模块,如系统的日志输出、人物管理器等。单例模式一般实现方式为:将类的构造函数定义成私有,定义一个私有的静态变量指针指向类得唯一实例,并提供一个公有静态方法获取该实例

 

简单实现

//Singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H
class Singleton
{
public:
static Singleton* getInstance();
private:
Singleton();
static Singleton* m_singleton;
};
#endif // SINGLETON_H
//Singleton.cpp
#include "singleton.h"
#include <iostream>
using namespace std;
//static变量的定义
Singleton* Singleton::m_singleton = NULL;
Singleton* Singleton::getInstance()
{
if(NULL == m_singleton)
{
m_singleton = new Singleton();
cout << "Singleton Create..." << endl;
}
return m_singleton;
}
Singleton::Singleton()
{
}
//main.cpp
#include "singleton.h"
#include <QtCore/QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Singleton *A = Singleton::getInstance();
Singleton *B = Singleton::getInstance();
return a.exec();
}

运行结果:

从运行结果可以知道Singleton对象只创建了一次,即创建两个Singleton对象发现只打印出一次Create... 即只调用了一次构造函数只生成了一个实例

 

深入思考

当在多线程中使用单例模式时(假设有AB两个线程),同时调用getInstance函数,初始时m_singletonNULL,当A线程调用getInstance时,执行到if(NULL==m_singleton)时,由于此时m_singletonNULL,默认情况下是要执行if里面的语句,但是由于CPU时间片到了等原因,先要去执行B线程,B线程执行到if(NULL==m_singleton)时,此时m_singleton同样为NULL。这种情况下就会出现问题,下面使用Qt中的互斥锁重写代码

//Singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H
#include <QMutex>
#include <QMutexLocker>
class Singleton
{
public:
static Singleton* getInstance();
private:
Singleton();
//定义静态成员 静态成员不属于某个对象 是属于整个类
static Singleton* m_singleton;
static QMutex mutex;
};
#endif // SINGLETON_H
//Singleton.cpp
#include "singleton.h"
#include <iostream>
using namespace std;
//static变量的定义
QMutex Singleton::mutex;
Singleton* Singleton::m_singleton = NULL;
Singleton* Singleton::getInstance()
{
//加锁
mutex.lock();
if(NULL == m_singleton)
{
m_singleton = new Singleton();
cout << "Singleton Create..." << endl;
}
//解锁
mutex.unlock();
return m_singleton;
}
Singleton::Singleton()
{
}


 


http://chatgpt.dhexx.cn/article/Ect9ww41.shtml

相关文章

单例模式介绍

目录 1 前言 2 单例模式类型 2.1 饿汉式&#xff1a; 2.2 懒汉式&#xff1a; 2.2.1 双重检查锁 2.2.2 volatile防止指令重排 2.3 静态内部类 3 破坏单例 1 前言 单例模式是指在内存中有且只会创建一次对象的设计模式&#xff0c;在程序中多次使用同一个对象且作用相同…

单例模式详解(附常见的7种单例模式源码)

单例模式&#xff08;Singleton Pattern&#xff09;:保证一个类仅有一个对象&#xff0c;并提供一个访问它的全局访问点。(Ensure a class only has one instance,and provide a globe point of access to it.) 常见应用场景&#xff1a; Windows的Task Manager&#xff08;…

设计模式(一)—单例模式(附Java代码)

单例模式&#xff08;Singleton Pattern&#xff09;:采取一定的方法保证在整个的软件系统中&#xff0c;对于某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其实例对象的方法。 比如Hibernate的SessionFactory&#xff0c;它充当数据存储源的代理&#xff0c;…

线程的运行状态

不管是多线程还是多进程&#xff0c;实际上都不太可能一直占用CPU资源&#xff0c;所有多线程的几种状态一定要掌握。 多线程的状态如下图&#xff1a; 所有的系统费资源是有限的&#xff0c;不管是多线程还是多进程都必须在执行一段时间后让出资源&#xff0c;交由其他的线程…

一条SQL语句统计总数及各状态数

需求&#xff1a;共有协议X份&#xff0c;已签XX份&#xff0c;待签X份 sql: select count(1) 总记录数,sum(case when XY_STATUS1 then 1 else 0 end)待签,sum(case when XY_STATUS2 then 1 else 0 end)已签 from YG.T_ZHGL 结果&#xff1a; count(1):所有数据&#xff…

线程的执行状态

1,创建&#xff1a; 当创建好线程对象的时候&#xff0c;也就是new Thread类或者是new Thread子类的时候。此时称为创建状态 2&#xff0c;就绪&#xff1a; 当线程对象调用了start&#xff08;&#xff09;方法&#xff0c;开启线程了的时候&#xff0c;此时的线程已经开启了&…

Java线程线程的状态

1、线程的状态 线程有六种状态&#xff1a;分别如下 ① NEW(新建) 线程刚被创建&#xff0c;但是并未启动。还没调用start方法 ② Runnable(可运行) 线程可以在java虚拟机中运行的状态&#xff0c;可能正在运行自己代码&#xff0c;也可能没有&#xff0c;这取决于操作系统…

Java多线程批量执行sql

当遇到大sql批量导入时几十万上百万数据&#xff0c;使用plsql执行等都是非常的慢。因此开发一套自定义线程池处理sql&#xff1a; 1&#xff0c;线程代码 import java.util.ArrayList;/*** ClassName: com.ai.order.esb.yulang.tools.handle* Description: TODO* version: v1…

一条SQL语句是如何执行的?

大家六一儿童节好呀&#xff01; 接下来的一段时间内&#xff0c;将带领大家一同探索MySQL的奥妙&#xff0c;加油吧&#xff01;我们。 下面进入正题&#xff1a;一条SQL语句是如何进行的&#xff1f; 对于这个问题&#xff0c;我想将其分为两个问题来回答&#xff0c;分别是…

mysql 查看线程状态

show full PROCESSLIST 打开两个查询窗口&#xff0c;在A窗口执行一个查询时间较长的sql&#xff0c;在B窗口使用show full PROCESSLIST&#xff0c;可以看到A中执行的sql时间。 sleep表示没有操作&#xff0c;query表示正在查询。

线程状态总结

目录 文章目录 前言 一、线程状态图解 二、线程的几种状态 及线程过程 1.线程的几种状态 2.线程过程 总结 前言 总结了在华清远见这段时间所学的线程相关的知识点&#xff0c;文章记录了线程的几种状态及线程的过程 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案…

线程状态

原文&#xff1a;https://mp.weixin.qq.com/s/GsxeFM7QWuR--Kbpb7At2w 人类为了利用好自己的时间&#xff0c;经常会同时做多件事情&#xff0c;比如上厕所时刷手机&#xff0c;开车时听新闻... 对于自己尚且如此&#xff0c;对计算机也不能闲着。为了最大化的提升机器利用率&…

一条SQL语句的执行过程

摘要 本文站在后端开发的角度&#xff0c;讲述一条SQL从客户端发送到MySQL服务器进行处理&#xff0c;并将结果返回给客户端的过程。这个过程中涉及的操作会在后面的文章中做详细的分析。 连接建立 我们通常使用ORM框架来生成SQL语句&#xff0c;在发送SQL语句给MySQL服务器…

多线程执行sql报错处理

pymysql多线程访问数据库报错&#xff1a;Packet sequence number wrong - got 7 expected 2 原文&#xff1a;https://www.cnblogs.com/heiao10duan/p/9373237.html参考&#xff1a;https://www.jianshu.com/p/60c8e0e440ea原因&#xff1a; 使用了多线程&#xff0c;多线程共…

MySQL - 一条 SQL 语句是如何执行的(SQL执行详解)

前言 天天和数据库打交道&#xff0c;一天能写上几十条 SQL 语句&#xff0c;但你知道我们的系统是如何和数据库交互的吗&#xff1f;MySQL 如何帮我们存储数据、又是如何帮我们管理事务&#xff1f;....是不是感觉真的除了写几个 「select * from dual」外基本脑子一片空白&a…

一、SQL语句执行过程

一、MySQL架构图 MySQL逻辑架构图&#xff0c;可以分为 Server 层和存储引擎层两部分。 Server 层包括连接器、查询缓存、分析器、优化器、执行器等&#xff0c;涵盖 MySQL 的大多数核心服务功能&#xff0c;以及所有的内置函数&#xff08;如日期、时间、数学和加密函数等&…

线程状态详解

线程的生命周期 new的时候即为创建状态。 调用start即为启动了&#xff0c;启动线程后就变为就绪状态&#xff0c; 就绪之后等待CPU的调度&#xff0c;CPU调度完之后&#xff0c;就进入了运行状态。 运行状态运行sleep方法时会进入阻塞状态&#xff0c;进入阻塞状态有非常多…

一条 SQL 语句是如何执行的

1. select 语句执行过程 一条 select 语句的执行过程如上图所示 1、建立连接 连接器会校验你输入的用户名和密码是否正确&#xff0c;如果错误会返回提示&#xff0c;如果正确&#xff0c;连接器会查询当前用户对于的权限。连接器的作用就是校验用户权限 2、查询缓存 MySQL…

SQL线程状态分析:processlist

老哥哔哔叨 我们已经写了很多 MySQL 的文章了&#xff0c;比如索引优化、数据库锁、主从复制等等。今天在来和大家学习一个优化方法&#xff1a;show processlist——查看当前所有数据库连接的 session 状态。帮助我们查看每个 SQL 线程的运行状态&#xff0c;是运行正常呀&…

线程的状态

1、线程有5种状态&#xff1a;新建&#xff08;new Thread&#xff09;、就绪&#xff08;runnable&#xff09;&#xff0c;运行&#xff08;running&#xff09;、阻塞&#xff08;blocked&#xff09;、结束&#xff08;dead&#xff09; 主要方法&#xff1a; setPriorit…