Singleton是单身模式,它是许多设计模式之一。该模型主要是为了确保类中只有一个实例,并提供了一个全局访问点可以访问它。
那么,为什么要设计单身模式?想象一下,如果系统中有日志类,则没有单个模式的设计;该日志可以在TXT文件中写入系统行为记录和异常信息。此系统中还有两个过程线程1和线程2。目前,这两个线程立即实例为对象,并调用该日志类的成员函数将信息写入日志文件。操作肯定会发生,并且快速执行过程所写的信息将以缓慢的执行速度涵盖。如何解决这个问题?当然,添加相互锁是一种方法,但是它会更麻烦。更好的解决方案是将类设计为单个案例类,而系统中只有一个可以存在。
单个示例模式的优点是,一方面,有很多对象可以创建如此多的对象,保存内存空间和保存系统文件手柄。(对于操作系统,文件句柄也是资源,不能随便浪费)
它只需要3个步骤:
应该注意的是,该函数返回对实例的引用。如果返回指针,则返回外部代码的风险。
请注意,此模式在访问该模式之前不会生成实例。该特征称为懒惰初始化,在初始化过程中会消耗大量的某些情况下,它具有很大的优势。
Lazy Singleton不是线程的安全。例如,线程A和线程B的判断现在通过,因此线程A和B将创建新的示例。单调模式确保生成独特实例的规则被打破。
由于主函数的初始化,因此没有线程安全性问题,但是潜在的问题是不同汇编单元中的无本地静态对象(函数外部静态对象)(可以理解为CPP文件和标头文件包含)该订单是未出示的。如果调用方法在完成初始化之前调用,则将返回定义的实例。
Scott Meyers使用局部静态对象(函数中的静态对象)提出了另一个更优雅的单例模式实现(项目04)(项目04)。在第一个访问方法时创建实例。
以下是两个线程的实现。
双检查锁定模式针对懒惰模式线程的安全转换。
如上所述,如果线程A和线程B通过了判决同时,可以实现线程安全性。这个想法的实现如下:
实际上,只有在创建对象时,您才需要排除面试判断,其余时间才能解锁。在实际执行过程中,即使创建实例对象成功,每个过程都会经常解锁和解锁会影响系统的运行效率。为了改善这种情况,可以在锁定之前做出判断。如果创建对象,则可以直接返回。如果未创建,则执行互操作性的互操作性。改进是双重检测锁定模式,代码如下:
双重检测模式的逻辑没有问题,但是在实际代码执行过程中仍然存在许多问题。用于审查的论文。
PTHREAD_ONCE通常用于一次性线程初始化。在整个语句周期中,此方法仅执行一次,以实现单个示例线程安全模式。
C ++的pthread_once()函数:
Muduo网络库的Singleton使用pthread_once。
BOOST ::不可复制的作用是使构造函数,分配值函数,破坏者并将构造函数声明复制为私人或保护。
单个模式的单线程实现相对简单,并且多线程实现更麻烦。双重检测锁定模式可能会受到实际操作中的基础硬件指令的影响,并生成非指望的结果。指令的问题,Java可以使用挥发性变量禁止JDK1.5之后的说明,因此DCL可以通过PTHREAD_ONCE模式解决线程安全问题。
1. https://blog.csdn.net/hit0803107/article/details/54411180
2. https://www.bilibili.com/read/cv14514506
3. https://blog.csdn.net/qq_40428665/article/details/84184414