首页 > 其他分享 >单例模式 lock 多线程 双重检查锁定机制

单例模式 lock 多线程 双重检查锁定机制

时间:2024-08-28 19:16:05浏览次数:13  
标签:Singleton 检查 lock uniqueInstance 实例 线程 单例 多线程

单例模式

单例模式

  public class Singleton
{
    // 定义一个静态变量来保存类的实例
    private static Singleton uniqueInstance;
    // 定义一个标识确保线程同步
    private static readonly object locker = new object();
    // 定义私有构造函数,使外界不能创建该类实例
    private Singleton()
    {
    }
    /// <summary>
    /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点
    /// </summary>
    /// <returns></returns>
    public static Singleton GetInstance()
    {// 双重锁定只需要一句判断就可以了
        if (uniqueInstance == null)
        {
            lock (locker)
            {
                // 如果类的实例不存在则创建,否则直接返回
                if (uniqueInstance == null)
                {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

这段代码定义了一个名为 Singleton 的类,它实现了单例模式。单例模式确保整个应用程序中该类只有一个实例,并提供一个全局访问点来获取这个实例。

具体来说:

  1. 私有静态成员 unique Instance 用于存储 Singleton 类的唯一实例。
  2. 私有静态对象 locker 用于保证多线程环境下实例化过程的线程安全。
  3. 私有构造函数 Singleton() 防止外部通过构造函数创建新实例。
  4. 公有静态方法 Get Instance() 提供了获取 Singleton 类实例的方法。该方法首先检查是否已存在实例,如果不存在,则在一个线程安全的区域内创建新实例;如果已存在,则直接返回现有实例。

这种实现方式采用了双重检查锁定(Double-Checked Locking)机制来优化性能,只在真正需要创建实例时执行同步操作。

双重检查锁定机制(Double-Checked Locking)

是一种在多线程环境中创建线程安全的单例实例的技术。它主要由两个部分组成:

  1. 第一次检查:在进入同步代码块之前,先检查实例是否已经被创建。如果实例已经存在,则直接返回该实例,避免不必要的同步开销。
  2. 第二次检查:如果第一次检查发现实例尚未创建,则进入同步代码块,在这个线程安全的区域内再次检查实例是否存在,如果仍然不存在,则创建实例。

这种方式可以减少同步代码块的执行次数,提高程序性能。在您提供的代码示例中,双重检查锁定机制体现在以下部分:

if (uniqueInstance == null) // 第一次检查
{
    lock (locker) // 进入同步区域
    {
        if (uniqueInstance == null) // 第二次检查
        {
            uniqueInstance = new Singleton(); // 创建实例
        }
    }
}

这里的关键在于,即使多个线程几乎同时到达第一次检查,大多数线程都会在第一次检查时返回,只有当 uniqueInstancenull 时,才会有一个线程进入锁区,并在那里再次检查 uniqueInstance 是否仍然为 null。如果此时 uniqueInstance 仍然为 null,则创建实例。这样可以确保只有一个线程能够创建实例,同时其他线程不会被阻塞,提高了效率和性能。

标签:Singleton,检查,lock,uniqueInstance,实例,线程,单例,多线程
From: https://www.cnblogs.com/zhuoss/p/18385403

相关文章

  • 【Java】多线程创建与管理 (实操图解)
    Java系列文章目录补充内容Windows通过SSH连接Linux第一章Linux基本命令的学习与Linux历史文章目录Java系列文章目录一、前言二、学习内容:三、问题描述四、解决方案:4.1Thread4.2Runnable五、总结:一、前言多线程入门二、学习内容:实现多线程效果三、问题......
  • c#关于同步 /异常/多线程/事件 事例
    sync同步async异步,要与await成对使用Thread //计算程序执行时间StopWatch sw=StopWatch.Start();转自:https://codeload.github.com/zhaoxueliang86/WinFormsAsyncAwait/zip/refs/heads/BilibiliB站UP主:银色 usingSystem.Diagnostics;usingSystem.Text;na......
  • C++学习随笔——lock_guard和mutex的使用方法
    std::mutex和std::lock_guard是C++标准库中用于多线程同步的工具,主要用于防止多个线程同时访问共享资源,导致数据竞争问题。 std::mutex是一个用于互斥锁的类,提供了锁定(lock)和解锁(unlock)的功能。使用方法:#include<iostream>#include<thread>#include<mutex>std::......
  • 单例模式
    1.单线程单例确保一个类只有一个实例,并提供一个访问它的全局访问点概念拆分(1.一个类只有一个实例2.提供一个全局访问点)publicclassSingleton{privatestaticSingletonsingleton;//定义一个静态变量来保护类的实例publicstaticSingleton......
  • C#环境下支持多线程的异步日志记录器的设计与实现
    上篇博文提供了c++版异步日志类,本文提供同样功能的C#版的异步日志管理类。C#环境下支持多线程的异步日志记录器的设计与实现在现代应用程序开发中,日志记录是一项至关重要的任务,它帮助开发者追踪程序的运行情况,调试问题,并进行性能监控。特别是在高并发场景下,传统的同步日志......
  • JS单例模式; super return 改变this
    简单的单例首先js中的函数是一种特殊的对象,这使得他可以存储属性functionaaa(params){}//undefinedaaa.lalala=123//123js中的类是通过原型链继承的,因此类就是函数的集合体,可以通过babel编译看看。因此可以写出简单的单例模式classSingleton{constructor(da......
  • Python系列(10)- Python 多线程
    多线程(Multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的系统包括对称多处理机、多核心处理器、芯片级多处理或同时多线程处理器。在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理”。多线程是并行化......
  • QT/C++中的GDAL多线程应用(读取):发生的问题以及解决方案
    1.引言在使用GDAL库对TIF文件进行切割和创建瓦片金字塔时,为了提高创建效率,不得不考虑使用多线程处理。然而,在实际实现过程中,我遇到了许多问题。通过不断的尝试和优化,最终找到了有效的解决方案。本文将详细记录这一过程中的问题和解决方法。2.初始多线程尝试与问题2.1......
  • VMware ESXi 8.0U3 macOS Unlocker & OEM BIOS Dell (戴尔) 定制版
    VMwareESXi8.0U3macOSUnlocker&OEMBIOSDell(戴尔)定制版ESXi8.0U3标准版,Dell(戴尔)、HPE(慧与)、Lenovo(联想)、Inspur(浪潮)、Cisco(思科)、Hitachi(日立)、Fujitsu(富士通)、NEC(日电)、Huawei(华为)、xFusion(超聚变)OEM定制版请访问原文链接:h......
  • 多线程的使用-->2
    1.线程同步当多线程执行,对于一个共享变量进行操作时,会产生一些安全问题,称为同步问题。线程同步就是在多线程访问共享变量时,通过一定的机制,使得线程可以按照一定的顺序,每次只能有一个线程访问共享变量。1.1解决线程同步给程序枷锁   两种:①.悲观锁:必须要上锁,有具体的......