【C#】C#中的线程安全:使用lock关键字确保共享资源的安全访问

embedded/2025/2/13 1:27:00/

文章目录

  • 前言
  • 一、为什么需要线程安全?
  • 二、示例代码
  • 三、代码解析
    • 1、同步对象的定义
    • 2、使用lock关键字
    • 3、双重检查锁定
  • 四、总结


前言

多线程编程中,确保对共享资源的安全访问是至关重要的。本文将讨论如何使用 lock 关键字和同步对象来实现线程安全,并提供一个简单的示例代码。

一、为什么需要线程安全?

多线程应用程序中,多个线程可能会同时访问和修改共享资源。如果没有适当的同步机制,可能会导致数据竞争和不一致的状态。例如,当两个线程同时尝试修改同一个变量时,可能会出现意想不到的结果。

二、示例代码

下面是一个使用 lock 关键字确保线程安全的示例代码。在这个示例中,我们将创建一个简单的日志记录器,确保在多线程环境中,日志记录的实例是唯一的。

using System;
using log4net;
using log4net.Config;
using System.IO;namespace ThreadSafeLogging
{public class LogHelper{private static object sync = new object(); // 定义同步对象private static ILog log = null; // 定义接口类型的字段private static ILog Log // 自动获取日志类型的属性{get{if (log == null){lock (sync) // 同步进行{if (log == null) // 双重检查锁定{// 加载配置文件XmlConfigurator.Configure(new FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile));log = LogManager.GetLogger(typeof(LogHelper)); // 获取实现了接口的具体实例}}}return log;}}public static void Info(string message){Log.Info(message);}public static void Error(string message, Exception ex){Log.Error(message, ex);}}class Program{static void Main(string[] args){// 示例:记录信息LogHelper.Info("Application started.");try{// 模拟异常throw new Exception("An error occurred.");}catch (Exception ex){LogHelper.Error("An error has been logged.", ex);}}}
}

三、代码解析

1、同步对象的定义

private static object sync = new object();

这里定义了一个静态对象 sync,用于作为锁定的基础对象。

2、使用lock关键字

lock (sync){if (log == null){// 创建日志实例}}

lock 关键字用于确保在同一时间只有一个线程可以进入锁定的代码块,从而避免数据竞争。

3、双重检查锁定

在锁定的代码块中,我们再次检查 log 是否为 null,以确保在创建日志实例时不会出现多个线程同时创建实例的情况。

四、总结

多线程环境中,使用 lock 关键字和同步对象是确保对共享资源安全访问的重要手段。通过合理的设计,可以避免数据竞争和不一致性的问题,从而提高程序的稳定性和可靠性。希望通过本文的示例,能够帮助你更好地理解 C# 中的线程安全。


http://www.ppmy.cn/embedded/161740.html

相关文章

CS架构软件网络安全 csf网络安全框架

美国依赖于其关键基础设施的可靠运行。 网络安全威胁利用了关键基础设施系统日益增加的复杂性和连通性,将国家的安全、经济以及公共安全和健康置于危险之中。 类似于金融和声誉风险,网络安全风险会影响公司的底线。 它会推高成本并影响收入,它…

Json-RPC项目框架(二)

目录 1. 项目实现; 1. 项目实现: 1.1 通信抽象实现: (1) BaseMessage: 主要实现对消息处理; 主要包含设置和获取ID, 设置类型和获取类型, 消息检查, 以及序列化和反序列化操作. class BaseMessage{public://大家需要的功能先实现;using ptr std::shared_ptr<BaseMessage…

linux基于 openEuler 构建 LVS-DR 群集--一、用命令行完成 二、使用脚本完成

目录 一、用命令行完成 1、在nginx上&#xff08;两台都是一样的配置&#xff09; 2、 在LVS上 1.&#xff09;绑定VIP &#xff08;与nginx上一致&#xff09; 2&#xff09;安装ipvsadm 3&#xff09;配置LVS-DR 3、在CLINT上 1&#xff09;验证 (验证成功如下) ​…

华为小艺助手接入DeepSeek,升级鸿蒙HarmonyOS NEXT即可体验

小艺助手接入DeepSeek的背景与意义 随着人工智能技术的不断发展&#xff0c;大模型成为推动智能交互升级的关键力量。DeepSeek在自然语言处理等领域具有出色的表现&#xff0c;其模型在语言理解、生成等方面展现出强大的能力。华为小艺助手接入DeepSeek&#xff0c;旨在借助其先…

LeetCode数学相关算法题(1)【C语言版】

2520. 统计能整除数字的位数 给你一个整数 num &#xff0c;返回 num 中能整除 num 的数位的数目。 如果满足 nums % val 0 &#xff0c;则认为整数 val 可以整除 nums 。 示例 1&#xff1a; 输入&#xff1a;num 7 输出&#xff1a;1 解释&#xff1a;7 被自己整除&…

黑马Redis详细笔记(实战篇---短信登录)

目录 一.短信登录 1.1 导入项目 1.2 Session 实现短信登录 1.3 集群的 Session 共享问题 1.4 基于 Redis 实现共享 Session 登录 一.短信登录 1.1 导入项目 数据库准备 -- 创建用户表 CREATE TABLE user (id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 用户ID,phone …

自动驾驶---如何打造一款属于自己的自动驾驶系统

在笔者的专栏《自动驾驶Planning决策规划》中&#xff0c;主要讲解了行车的相关知识&#xff0c;从Routing&#xff0c;到Behavior Planning&#xff0c;再到Motion Planning&#xff0c;以及最后的Control&#xff0c;笔者都做了相关介绍&#xff0c;其中主要包括算法在量产上…

React进行路由跳转的方法汇总

在 React 中进行路由跳转有多种方法&#xff0c;具体取决于你使用的路由库和版本。以下是常见的路由跳转方法汇总&#xff0c;主要基于 react-router-dom 库。 1. 使用 useNavigate 钩子&#xff08;适用于 react-router-dom v6&#xff09; useNavigate 是 react-router-dom…