C#线程同步的三类情景分析

yizhihongxing

C#线程同步的三类情景分析

在多线程的应用中,为了确保数据的正确性,我们需要对线程进行同步,避免多个线程同时对同一份数据进行修改。C#中提供了多种同步机制,其中包括线程同步的三类情景:Mutex、Monitor和AutoResetEvent。

Mutex

Mutex是由操作系统提供的同步原语,可以保证只有一个线程访问临界区。典型的使用方式如下:

using System.Threading;

Mutex mutex = new Mutex();

void Method1()
{
    mutex.WaitOne();
    try 
    {
        // 临界区代码
    }
    finally 
    {
        mutex.ReleaseMutex();
    }
}

void Method2()
{
    mutex.WaitOne();
    try 
    {
        // 临界区代码
    }
    finally 
    {
        mutex.ReleaseMutex();
    }
}

这里使用Mutex来保护两个方法中的临界区,确保它们不会被同时访问。当一个线程获得了Mutex的锁时,其他线程将会阻塞,直到拥有锁的线程释放它。

Monitor

Monitor是.NET Framework提供的同步机制,它可以保证在同一时间内只有一个线程访问临界区。典型的使用方式如下:

using System.Threading;

object lockObject = new object();

void Method1()
{
    lock(lockObject) 
    {
        // 临界区代码
    }
}

void Method2()
{
    lock(lockObject) 
    {
        // 临界区代码
    }
}

这里使用lock关键字来保证两个方法中的临界区不会同时被访问。当一个线程进入临界区时,其他线程将会阻塞,直到当前线程离开临界区。

AutoResetEvent

AutoResetEvent是一个基于事件的同步机制,它允许一个线程等待另一个线程的信号。典型的使用方式如下:

using System.Threading;

AutoResetEvent autoEvent = new AutoResetEvent(false);

void Method1()
{
    // 临界区代码
    autoEvent.Set();
}

void Method2()
{
    autoEvent.WaitOne();
    // 临界区代码
}

这里使用AutoResetEvent来等待Method1的信号,当Method1完成临界区操作后,调用autoEvent.Set()来通知正在等待的线程。Method2调用autoEvent.WaitOne()来等待信号的到来,从而保证临界区操作的同步性。

示例说明

下面是两个示例,演示了如何使用Mutex和Monitor来保护共享资源。

Mutex示例

using System.Threading;

class Counter
{
    private int count = 0;
    private Mutex mutex = new Mutex();

    public void Increment()
    {
        mutex.WaitOne();
        try 
        {
            count++;
        }
        finally 
        {
            mutex.ReleaseMutex();
        }
    }

    public void Decrement()
    {
        mutex.WaitOne();
        try 
        {
            count--;
        }
        finally 
        {
            mutex.ReleaseMutex();
        }
    }

    public int GetCount()
    {
        mutex.WaitOne();
        try 
        {
            return count;
        }
        finally 
        {
            mutex.ReleaseMutex();
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Counter c = new Counter();
        Thread t1 = new Thread(() => {
            for(int i = 0; i < 100000; i++) 
            {
                c.Increment();
            }
        });
        Thread t2 = new Thread(() => {
            for(int i = 0; i < 100000; i++) 
            {
                c.Decrement();
            }
        });
        t1.Start();
        t2.Start();
        t1.Join();
        t2.Join();
        Console.WriteLine($"Count: {c.GetCount()}");
    }
}

这个示例演示了如何使用Mutex来保护一个计数器的临界区。Counter类有三个方法:Increment、Decrement和GetCount,这些方法分别执行对计数器的加、减和读操作。每个方法都获取Mutex的锁,并在临界区执行相应的操作。需要注意的是,在GetCount方法中也需要获取Mutex的锁,以保证读操作的安全性。

Monitor示例

using System.Threading;

class BankAccount
{
    private int balance = 0;

    public void Deposit(int amount)
    {
        lock(this) 
        {
            balance += amount;
        }
    }

    public void Withdraw(int amount)
    {
        lock(this) 
        {
            if(balance >= amount)
            {
                balance -= amount;
            }
            else 
            {
                throw new Exception("Insufficient funds");
            }
        }
    }

    public int GetBalance()
    {
        lock(this) 
        {
            return balance;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        BankAccount account = new BankAccount();
        Thread t1 = new Thread(() => {
            for(int i = 0; i < 100000; i++) 
            {
                account.Deposit(10);
            }
        });
        Thread t2 = new Thread(() => {
            for(int i = 0; i < 100000; i++) 
            {
                account.Withdraw(10);
            }
        });
        t1.Start();
        t2.Start();
        t1.Join();
        t2.Join();
        Console.WriteLine($"Balance: {account.GetBalance()}");
    }
}

这个示例演示了如何使用Monitor来保护一个银行账户的临界区。BankAccount类有三个方法:Deposit、Withdraw和GetBalance,这些方法分别执行对账户余额的存、取和读操作。使用lock(this)来获取锁,确保每个方法执行时都只有一个线程能够访问临界区。需要注意的是,在Withdraw方法中,如果余额不足,则会抛出异常。同时,GetBalance方法也会获取锁,以保证读操作的安全性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#线程同步的三类情景分析 - Python技术站

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

相关文章

  • C#中Hash table的一些操作方法讲解

    哈希表(Hash table)是一种常见的数据结构,用于存储键值对(key-value pairs)。在C#中,可以使用System.Collections.Hashtable类来创建一个哈希表对象,它提供了各种方法来管理键值对。 以下是一些C#中哈希表的操作方法的详细讲解: 创建哈希表对象 可以通过以下代码来创建一个哈希表对象: Hashtable has…

    C# 2023年5月31日
    00
  • C#学习基础概念二十五问续2

    “C#学习基础概念二十五问续2”是一篇介绍C#语言基础概念的文章,主要讲解了25个问题。以下是这篇文章的完整攻略: 1. 概述 在概述中,应该简要介绍文章的主题和内容,解释本文旨在帮助哪些读者,以及文章的阅读难度等信息。 2. C#是什么 这一节主要介绍了C#是一种什么类型的语言,它的特点和用途是什么等等。这里可以举一个示例,如以展示C#代码如何使用控制台输…

    C# 2023年6月6日
    00
  • C#反射(Reflection)对类的属性get或set值实现思路

    C#反射(Reflection)是C#语言的一项重要特性,它允许在运行时动态的访问和修改.NET程序集中的类型信息。其中,对类的属性进行get或set值也是Reflection的核心功能之一。 在C#中,类的属性可以使用get和set来定义。其中,get可以取得该属性的值,而set可以设置该属性的值。而反射(Reflection)则可以通过以下的步骤来获取和…

    C# 2023年5月31日
    00
  • c#使用正则表达式匹配字符串验证URL示例

    下面是详细讲解c#使用正则表达式匹配字符串验证URL的完整攻略。 什么是正则表达式 正则表达式是一种用于匹配文本的工具,它可以用来查找、替换或者检测文本中符合特定格式的字符串。 在c#中,.NET框架提供了使用正则表达式的类库,通过这些类库可以方便的进行字符串匹配的操作。 如何使用正则表达式匹配URL 在c#中,我们可以使用Match类提供的方法来进行正则表…

    C# 2023年6月8日
    00
  • 记录.Net部署Docker-v指令使用

    记录Docker的-v指令使用 前言 之前我浅学了一下docker,方便部署.net项目(部署的是打包之后的项目) dockerfile文件如下: FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 5031 EXPOSE 7031 FROM mcr.microsoft.c…

    C# 2023年4月25日
    00
  • .NET Core中的HttpClientFactory类用法详解

    .NET Core中的HttpClientFactory类用法详解 在.NET Core中,使用HttpClient发出Http请求的场景非常普遍,而且HttpClient由于某些原因并不是线程安全的,所以我们通常需要注意HttpClient的生命周期和使用方式。HttpClientFactory则为我们提供了方便的HttpClient管理机制。 HttpC…

    C# 2023年6月3日
    00
  • C#实现获取mp3 Tag信息的方法

    C#实现获取mp3 Tag信息的方法 概述 在C#中,我们可以利用第三方库来获取mp3文件的Tag信息,比如使用TagLibSharp库。Tag信息是一些元数据,包括歌曲名、演唱者、专辑名、年份等等。获取Tag信息可以使我们更好地管理和组织音乐文件。 步骤 1. 安装TagLibSharp库 首先,我们需要安装一个名为TagLibSharp的第三方库,可以在…

    C# 2023年6月7日
    00
  • 基于.net4.0实现IdentityServer4客户端JWT解密

    针对“基于.net4.0实现IdentityServer4客户端JWT解密”的完整攻略,具体步骤如下: 1.创建新项目 使用Visual Studio创建一个新项目,选择“ASP.NET Web应用程序”模板,创建后选择“Web API”模板,目标框架版本选为“.NET Framework 4.7.2”。创建完成后进入解决方案资源管理器,右键单击项目名称,选…

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