0
using System;
using System.Threading;

class Program
{
    private static int i = 0;
    private static volatile int j = 0;

    static void Main(string[] args)
    {
        Timer timer = new Timer(TimeCallback, null, 1000, 60 * 1000);


        Console.ReadLine();
    }

    private static void TimeCallback(object state)
    {
        i++;
        if (i > 10000 * 10000)
        {
            i = 0;
        }

        j++;
        if (j > 10000 * 10000)
        {
            j = 0;
        }


        Console.WriteLine(i + "," + j);
    }
}

In above code, TimeCallback run very fast, it can't run concurrently during the timer's interval. So I Know it is atomic, no need to lock().

My question is, does i can be non volatile, or it must be volatile like j.

If i must be volatile, how does akka actor field can be non volatile?

Should my Akka actors' properties be marked @volatile?

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
lcm
  • 531
  • 1
  • 5
  • 6

1 Answers1

1

If only one thread, other than the main thread, uses some variables and we are sure it will never be used by another thread, it's like single-threaded, so we don't need to deal with concurrency and synchronization (locked, volatile, Monitor ...).

The only thing we can and should do to be scrupulous is make sure that we separate the code and use good namings as well as dedicated class.

For example:

class Program
{
  static void Main(string[] args)
  {
    Timer timer = new Timer(MyIsolatedThreadedProcessing.DoProcess, null, 1000, 60 * 1000);
    Console.ReadLine();
  }
}

static public class MyIsolatedThreadedProcessing
{
  static private int Value1 = 0;
  static private int Value2 = 0;
  static public void DoProcess(object state)
  {
    Value1++;
    if ( Value1 > 10000 * 10000 )
    {
      Value1 = 0;
    }
    Value2++;
    if ( Value2 > 10000 * 10000 )
    {
      Value2 = 0;
    }
    Console.WriteLine(Value1 + "," + Value2);
  }
}

But anything used and shared between threads need to be managed as required, even readings in general.

So if multiple threads can call the timer callback at the same time, you indeed have to manage concurrency and synchronization because it is multithreading.

You wrote "it can't run concurrently during the timer's interval" and "Timer callback is executed on threadpool, It may run on different thread": So never assume something like "TimeCallback run very fast", ever.

Therefore you should do the things in a clean, sturdy, and standard way. Thus you will avoid elementary problems and occasional random crashes or freezes.

Threading in C#

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459