C# 线程安全:在一个线程中读取变量同时在另一个线程中更新该变量会导致意外行为吗?

Posted

技术标签:

【中文标题】C# 线程安全:在一个线程中读取变量同时在另一个线程中更新该变量会导致意外行为吗?【英文标题】:C# thread safety: can reading variable in one thread WHILE updating that variable in another lead to unexpected behavior? 【发布时间】:2018-10-15 05:13:57 【问题描述】:

以这个程序为例:

class Program

   public static double myVar1 = 0;
   public static double myVar2 = 0;

   static void Main()
   
      Thread thread1 = new Thread(new ThreadStart(update_variable));
      thread1.Start();

      while (true)
      
         myVar2 = myVar1;
      
   

   static update_variable()
   
      while (true)
      
         myVar1 = 2222222.22;
         myVar1 = 1111111.11;
      
   

myVar2 是否有可能等于 222222.22 或 1111111.11 以外的值?换句话说,变量的字节是“全部改变还是全部改变”,或者当一些字节发生改变而其他字节没有改变时,主线程能否及时看到 myVar1 的实例,从而给出意外的值?

我已经测试了上面的程序并没有看到这种行为,但我想知道它是否可能以及这是否会被视为线程安全代码。我宁愿不使用锁的资源,因为我只有一个线程更改数据和一个使用数据的线程。

【问题讨论】:

Specification:其他类型的读写,包括longulongdoubledecimal,以及用户自定义类型,不保证是原子的。 【参考方案1】:

回答你的问题,是的,有可能; double 中的某些字节可能会在其他线程读取该值时更新,因此会包含损坏的数据。

如果您对不使用lock 的原子读写方式感兴趣,我建议您查看支持有限原子操作集的Interlocked 类。

另见c# interlocked methods as a locking mechanism?。

【讨论】:

以上是关于C# 线程安全:在一个线程中读取变量同时在另一个线程中更新该变量会导致意外行为吗?的主要内容,如果未能解决你的问题,请参考以下文章

C ++如果一个线程写入一旦完成就会切换一个布尔值,那么在另一个线程的循环中读取该布尔值是不是安全?

C# 线程安全与 lock锁

C#复习总结探究各类数据结构(ArrayListQueueStack)及线程安全问题和yeild关键字

C# 多线程同步访问一个文件怎么处理

一个线程读取和另一个写入 volatile 变量 - 线程安全?

JSP线程安全