ilovecomputer66 发表于 2023-5-21 09:28

C#这里该不该加volatile ?

本帖最后由 ilovecomputer66 于 2023-5-21 09:34 编辑

我用C#写类似java的AtomicInteger类。第3行这个volatile   该不该加?chatGPT上让他找别人写的这个代码,是没有加的。第一次问他,难道不该加volatile么?他说原子操作,不用加。我反问,那你get方法就直接拿_value的值,又不是原子操作,多线程不加volatile,难道不会读到脏值?他说他错了,应该加。那我让他再写一遍,它又不加,和神经病似的


反正我觉得是得加这个volatile,或者用Interlocked.Read方法返回_value的值(但C#只提供long型的Interlocked.Read作为返回值,又要转类型,又因为原子操作比可见性还要重,相比就不如加volatile


不知道大家怎么看, 觉得该加么

    public class AtomicInteger
    {
      private volatile int _value;

      public int Value
      {
            get { return _value; }
            set { Interlocked.Exchange(ref _value, value); }
      }

      public int GetAndIncrement()
      {
            return Interlocked.Increment(ref _value) - 1;
      }

      public int GetAndDecrement()
      {
            return Interlocked.Decrement(ref _value) + 1;
      }

      public int IncrementAndGet()
      {
            return Interlocked.Increment(ref _value);
      }

      /// <summary>
      /// 通过原子操作,对原值进行增减
      /// </summary>
      /// <param name="delta">要增减的值,增加为正数,减少为负数</param>
      /// <returns>进行增减后的值</returns>
      public int ChangeAndGet(int delta)
      {
            return Interlocked.Add(ref _value, delta);
      }

      public int DecrementAndGet()
      {
            return Interlocked.Decrement(ref _value);
      }
    }

jimoguying2020 发表于 2023-5-21 09:46

在 C# 中,volatile 关键字用于指示一个变量的值是可变的,并且该变量可能被其他线程或进程修改。对于一个共享资源,如果其他线程或进程可以看到并且修改它的值,就可能导致并发错误或竞争条件。
在你的 AtomicInteger 类中,volatile 关键字可以提高并发性能,因为它可以确保当多个线程或进程同时访问同一个变量时,它们可以看到该变量的最新值。因此,建议你在 AtomicInteger 类中使用 volatile 关键字。
当然,在实际使用时,你需要考虑到 volatile 关键字可能带来的一些副作用,例如可能会降低程序的性能,因为它可能会导致更多的指令级别的操作。因此,你需要根据具体情况来决定是否需要使用 volatile 关键字。

ilovecomputer66 发表于 2023-5-21 09:58

jimoguying2020 发表于 2023-5-21 09:46
在 C# 中,volatile 关键字用于指示一个变量的值是可变的,并且该变量可能被其他线程或进程修改。对于一个 ...

我感觉你问的是chatgpt,这个口吻很像。我上面说了,chatgpt就很像 胡某进,一会一变,不靠谱的很

goldli 发表于 2023-5-21 12:15

本帖最后由 goldli 于 2023-5-21 22:03 编辑

~~~~~~~~~

天心阁下 发表于 2023-5-21 12:17

public int Value
    {
      get { return Interlocked.CompareExchange(ref _value,0,0); }
      set { Interlocked.Exchange(ref _value, value); }
    }
volatile就不用了
Interlocked.Read反编译也是用CompareExchange

ilovecomputer66 发表于 2023-5-21 14:36

天心阁下 发表于 2023-5-21 12:17
public int Value
    {
      get { return Interlocked.CompareExchange(ref _value,0,0); }


我还是说,能只用可见性解决,为什么要用原子性,加更重效率更低的锁?

天心阁下 发表于 2023-5-21 19:11

ilovecomputer66 发表于 2023-5-21 14:36
我还是说,能只用可见性解决,为什么要用原子性,加更重效率更低的锁?

VS写C语言带过来的,警告 C28112
页: [1]
查看完整版本: C#这里该不该加volatile ?