.NET 中的 3 个多线程示例

作者:微信公众号:【架构师老卢】
3-12 15:53
23

概述:多线程似乎是我的听众非常感兴趣的东西。事实上,从一开始,我浏览次数最多的文章之一就是关于任务与线程的:软件面试问题:.NET 中的任务 VS 线程.NET 中的任务和线程有什么区别:初级到高级线程确实是软件工程师可以拥有的最重要的技能。这就是为什么在以后的文章中,我计划创建一个关于编程中多线程的广泛内容。今天,我们正在探索一个新的软件工程面试问题。编程中使用的 volatile 关键字是什么?(.NET 示例)在我们开始之前,我想花一分钟时间对我的每一位成员表示衷心的感谢!你们真是太棒了,花在写这些文章上的每一秒都是值得的!谢谢!话虽如此,将您的战利品放在一个舒适的位置,让我们开始吧!介绍在多

多线程似乎是我的听众非常感兴趣的东西。事实上,从一开始,我浏览次数最多的文章之一就是关于任务与线程的:

软件面试问题:.NET 中的任务 VS 线程

.NET 中的任务和线程有什么区别:初级到高级

线程确实是软件工程师可以拥有的最重要的技能。这就是为什么在以后的文章中,我计划创建一个关于编程中多线程的广泛内容。

今天,我们正在探索一个新的软件工程面试问题。

编程中使用的 volatile 关键字是什么?(.NET 示例)

在我们开始之前,我想花一分钟时间对我的每一位成员表示衷心的感谢!你们真是太棒了,花在写这些文章上的每一秒都是值得的!谢谢!

话虽如此,将您的战利品放在一个舒适的位置,让我们开始吧!

介绍

在多线程编程中,确保跨线程共享数据的正确同步和可见性对于避免争用条件和确保数据一致性至关重要(数据应该在使用它的每段代码之间匹配)。.NET 为解决这些问题而提供的一种工具是关键字。volatile

在本文中,我们将通过 3 个代码示例深入探讨关键字的用法、其含义以及它如何帮助管理多线程环境中的共享数据。volatile

我总是尽量让我的文章保持半个人化。我确实会谈论一些私人的东西,并试图让它不那么无聊,因为学习可能很乏味,老实说。

这就是为什么你会发现一个专业结构的谚语,然后突然在下面,你会发现我试图用不同的词来解释它,很可能听起来像一匹沉闷的马。

在这个小小的旅行之后,将挥发性考虑为以下事情。

优化谈判代表

仅此而已。它实际上只是说编译器应该优化什么,不应该优化什么。或者更准确地说,它只是与编译器交谈并说出以下内容:

拜托,不要在这里尽力优化这个东西!

让我们再次更专业地对待事情。

不稳定 — 谈判者

C# 中的关键字用于指示字段可能由同时执行的多个线程修改。通过将字段标记为 ,编译器和运行时将被告知,对该字段的任何访问都应直接对内存进行,从而绕过可能采用的任何缓存机制。这可确保一个线程所做的更改立即对其他线程可见。volatilevolatile

示例 1️⃣volatile 关键字的基本用法:

class SharedData  
{  
    public volatile bool flag;  
}  
  
class Program  
{  
    static void Main(string[] args)  
    {  
        SharedData data = new SharedData();  
  
        // Thread 1  
        new Thread(() =>  
        {  
            while (!data.flag) { }  
            Console.WriteLine("Thread 1: Flag is set to true.");  
        }).Start();  
  
        // Thread 2  
        new Thread(() =>  
        {  
            Thread.Sleep(1000); // Simulate some work  
            data.flag = true;  
            Console.WriteLine("Thread 2: Flag set to true.");  
        }).Start();  
    }  
}

在此示例中,我们有一个标记为 的共享布尔标志。线程 1 在循环中不断检查此标志的值,直到它变为 true。同时,线程 2 在短暂延迟后将标志设置为 true。flagvolatile

如果没有关键字,线程 1 可能会缓存线程 2 的值,并且永远不会看到线程 2 所做的更改。但是,使用 ,对 的更改立即对所有线程可见。volatileflagvolatileflag

示例 2️⃣使用具有双重检查锁定模式的易失性

class Singleton  
{  
    private static volatile Singleton instance;  
    private static readonly object lockObject = new object();  
  
    private Singleton() { }  
  
    public static Singleton Instance  
    {  
        get  
        {  
            if (instance == null)  
            {  
                lock (lockObject)  
                {  
                    if (instance == null)  
                    {  
                        instance = new Singleton();  
                    }  
                }  
            }  
            return instance;  
        }  
    }  
}

在这个经典的单例实现中,该字段被标记为,以确保对此字段的任何写入都立即对其他线程可见。这可以防止由于线程缓存而可能出现的潜在问题,尤其是在双重检查锁定阶段,多个线程可能会同时检查并创建实例。instancevolatile

示例 3️⃣使用读取和写入方法

class Example  
{  
    private static volatile int count = 0;  
  
    public static void IncrementCount()  
    {  
        int temp = Volatile.Read(ref count); // Read count  
        temp++; // Modify temp  
        Volatile.Write(ref count, temp); // Write temp back to count  
    }  
}

有时,在处理易失性变量时,可能需要对内存屏障进行更精细的控制。和 方法提供此类控制。Volatile.ReadVolatile.Write

在此示例中,确保读取最新的值 ,并确保修改后的值立即写回 ,绕过任何潜在的缓存机制。Volatile.ReadcountVolatile.Writecount

结论

编程中的关键字是用于管理多线程应用程序中的共享数据的宝贵工具。通过适当使用它,您可以确保一个线程所做的更改立即对其他线程可见,从而防止潜在的同步问题。

相关留言评论
昵称:
邮箱:
阅读排行