C#单例模式与多线程用法介绍

C#单例模式与多线程用法介绍

单例模式是C#编程中最常用的面向对象设计模式之一,在多线程环境下实现单例模式要注意线程安全问题。本文将从以下几个方面进行介绍:

  • 单例模式的概念及说明
  • 单例模式的实现方式
  • 多线程环境下的单例模式实现
  • 示例代码介绍

单例模式概述

单例模式是指一个类只能被实例化一次,通过提供全局唯一的访问点,来确保该类的对象只有一个。单例模式在多线程环境下应用很广泛,因为多线程环境下创建多个实例可能会影响程序的稳定性和性能。

单例模式实现方式

在C#中实现单例模式有多种方式,这里介绍较为常用的两种实现方式。

方式一:饿汉模式

饿汉模式指的是在程序启动的时候就创建对象。这样做的好处是保证了对象的唯一性和线程安全,但也有一个缺点,就是如果对象很大或者创建起来很耗时,会导致程序启动时间变长。

示例代码如下:

public class Singleton  
{  
    private static Singleton instance = new Singleton();  
    private Singleton(){}  
    public static Singleton GetInstance()  
    {  
        return instance;  
    }  
} 

方式二:懒汉模式

懒汉模式指的是在第一次访问的时候才创建对象。这种方式看起来更加灵活,但也有一个问题,就是在多线程环境下可能会导致创建多个实例的情况。为了避免这种情况,我们可以通过加锁或使用静态构造函数实现线程安全。

示例代码如下:

public class Singleton  
{  
    private static Singleton instance = null;  
    private static readonly object obj = new object();  
    private Singleton(){}  
    public static Singleton GetInstance()  
    {  
        if(instance == null)  
        {  
            lock(obj)  
            {  
                if(instance == null)  
                {  
                    instance = new Singleton();  
                }  
            }  
        }  
        return instance;  
    }  
} 

多线程环境下的单例模式实现

多线程环境下实现单例模式需要注意线程安全问题。常见的做法有使用静态构造函数或者加锁,这里以使用静态构造函数为例进行介绍。

示例代码如下:

public class Singleton  
{  
    private static Singleton instance = null;  
    private static readonly object obj = new object();  
    private Singleton(){}  
    static Singleton()  
    {  
        instance = new Singleton();  
    }  
    public static Singleton GetInstance()  
    {  
        return instance;  
    }  
} 

在上面的示例代码中,使用了静态构造函数来保证线程安全。因为在类第一次被使用时,CLR会自动调用静态构造函数,只有一个线程会执行这个构造函数。

示例代码介绍

下面通过两个示例代码来说明单例模式的应用场景和使用方法。

示例一:Windows窗口

我们知道,在Windows操作系统中,每个窗口都有一个句柄,用于标识这个窗口。为了避免同一个窗口有多个句柄,Windows采用了单例模式来管理窗口的句柄。

示例代码如下:

public class Window  
{  
    private static readonly object obj = new object();  
    private static Window instance = null;  
    private int handle;  
    private Window()  
    {  
        handle = GetWindowHandle();  
    }  
    public static Window GetInstance()  
    {  
        lock(obj)  
        {  
            if(instance == null)  
            {  
                instance = new Window();  
            }  
        }  
        return instance;  
    }  
    private int GetWindowHandle()  
    {  
        // 获取窗口句柄的代码  
        return handle;  
    }  
}  

示例二:日志记录器

在程序开发过程中,我们通常需要记录一些日志信息。为了确保日志信息写入的一致性,我们可以使用单例模式来实现日志记录器。

示例代码如下:

public class Logger  
{  
    private static Logger instance = null;  
    private static readonly object obj = new object();  
    private StreamWriter writer = null;  
    private Logger()  
    {  
        string fileName ="log.txt";  
        writer = File.CreateText(fileName);  
    }  
    public static Logger GetInstance()  
    {  
        if(instance == null)  
        {  
            lock(obj)  
            {  
                if(instance == null)  
                {  
                    instance = new Logger();  
                }  
            }  
        }  
        return instance;  
    }  
    public void WriteLog(string message)  
    {  
        writer.WriteLine("{0} - {1}", DateTime.Now.ToString(), message);  
        writer.Flush();  
    }  
} 

以上就是C#单例模式与多线程用法介绍的完整攻略。希望本文能对大家学习和使用单例模式有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#单例模式与多线程用法介绍 - Python技术站

(0)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • C#中获取数据的方法实例

    以下是详细讲解C#中获取数据的方法实例的完整攻略: 一、获取数据的方法 在C#中,常见的数据获取方法有以下几种: ADO.NET(ActiveX Data Objects.NET) Entity Framework LINQ WCF Data Services Web API 其中,ADO.NET是最基础、最常用、最灵活的方法,我们这里就以ADO.NET为例…

    C# 2023年6月8日
    00
  • 浅谈C#9.0新特性之参数非空检查简化

    首先,C# 9.0中引入的新特性包含了很多实用的语言功能,其中参数非空检查简化就是其中之一。在传统的C#语言中,我们常使用条件判断语句来检查参数是否为null,这样代码可读性较差,而C# 9.0中的新特性可以更加方便快捷地进行参数非空检查。 简化前的参数非空检查 在C# 9.0之前,我们通常使用以下方式来进行参数非空检查: void PrintMessage…

    C# 2023年5月15日
    00
  • asp.net 身份验证机制实例代码

    ASP.NET身份验证是一种灵活的机制,用于验证用户身份、授权访问和管理会话对象。实现身份验证需要使用ASP.NET提供的一些特定的类和方法,本文将带你通过实例代码学习如何使用ASP.NET身份验证机制。 步骤一:启用ASP.NET身份验证 首先,你需要在Web.config文件中启用ASP.NET身份验证。在标签下添加如下配置: <system.we…

    C# 2023年5月31日
    00
  • .NET Core中使用Redis与Memcached的序列化问题详析

    .NET Core 中使用 Redis 与 Memcached 的序列化问题详析 在 .NET Core 中,Redis 和 Memcached 是两个非常流行的缓存解决方案。在使用 Redis 和 Memcached 时,序列化是一个非常重要的问题。本攻略将详细介绍在 .NET Core 中使用 Redis 和 Memcached 时的序列化问题,并提供多…

    C# 2023年5月17日
    00
  • C# WebApi 异常处理解决方案

    下面是关于C# WebApi异常处理的完整攻略: 1. 异常分类 程序完成预期业务逻辑,但无法继续执行下去,抛出了异常,如空引用异常、下标越界异常等。 业务逻辑处理不符合预期或不符合要求,可以抛出自定义异常。 2. 异常处理方案 通过自定义过滤器来实现统一的异常处理。 2.1 自定义Exception类 首先定义一个自定义的异常类,需要继承自Exceptio…

    C# 2023年5月14日
    00
  • CodeBuilder 3 预览版发布

    CodeBuilder是一款强大的代码生成工具,目前发布了 3.0 preview 2,大家可以前去下载体验 官方主页。 1、多种数据源 基于 ADO.NET 的数据驱动 基于 Fireasy 3,支持从 SqlServer、MySql、Oracle、Firebird、PostgreSql、SQLite、达梦、人大金仓、神通数据库,以及 OleDb 驱动。可…

    C# 2023年4月22日
    00
  • C# TreeView无限目录树实现方法

    C# TreeView无限目录树的实现方法可以通过以下步骤完成。 步骤一:设计树状结构 在设计树状结构时,考虑到每个文件夹可以包含多个子文件夹和文件,我们需要设计一个包含以下字段的Folder类: public class Folder { public string Name { get; set; } // 文件夹名称 public string Pat…

    C# 2023年6月8日
    00
  • C#中常使用进度条的代码

    让我来为你讲解如何在C#应用程序中使用进度条的代码。 1. 创建进度条控件 在Visual Studio中创建一个新的Windows Forms应用程序项目。然后,找到工具箱中的“ProgressBar”控件并将其拖放到窗体上。可以通过设置控件的属性来更改进度条的外观和行为,例如使进度条水平或垂直、更改颜色等等。 2. 编写代码更新进度条 进度条的名称应该是…

    C# 2023年6月7日
    00
合作推广
合作推广
分享本页
返回顶部