0

  • As of 2022. May. 1

For someone who's encountered this question, please check

Is C# Random Number Generator thread safe?

as I believe the answer there is useful.


Consider the following code example. I have a class Randomiser that has a static member variable public static Random rand. I can instantiate the Randomiser object as many times as I want, while I can access the member variable public static Random rand at any scope. At each time I call rand.Next(), I expect that the variable rand changes its status. In particular, I can call rand.Next() in multiple threads as in the example code.

Because the Random rand is a static variable, any call of rand.Next() method will refer to the same memory stack, and it is supposed to use the same random states. This does not have any issue if rand.Next() is called in a single process as they will be executed in a sequential order and the random state is not mixed up. However, when multiple threads are invoking the rand.Next() method, and if they happen to call it exactly at the same time, if this is somehow possible, it is unclear how the random state should change; rand.Next() is not only a read-access but it also changes the random state.

It appears to be a very theoretical and even weird question, but is there anyone who can imagine what is going to happen to the Random rand's random state when multiple threads are invoking at identical CPU clock?

    class Randomiser
    {
        public static Random rand = new 
                      Random(DateTime.UtcNow.GetHashCode());
                  
        public Randomiser(in string _name_) { this.name = _name_; }

        public string name = "";
        public int    num = -1;
    }
    class Program
    {   
        static void Main()
        {
            Randomiser[] Guys = 
            { 
                new Randomiser("Charlie"), 
                new Randomiser("Fox")
            };

            double for_ = 0.1;
            bool run = true;
            var t0 = DateTime.UtcNow;   
            
            new Thread(()=>
            { 
                while(run) 
                { 
                    Guys[0].num = Randomiser.rand.Next(); 
                    Console.WriteLine($"{Guys[0].name}: {Guys[0].num}");
                } 

            }).Start();

            new Thread(()=>
            { 
                while(run) 
                { 
                    Guys[1].num = Randomiser.rand.Next(); 
                    Console.WriteLine($"{Guys[1].name}: {Guys[1].num}");
                } 

            }).Start();
            
            while (true)
            {
                if ((DateTime.UtcNow - t0).TotalSeconds > for_)
                {
                    run = false;
                    break;
                }
            }
        }

        Console.ReadLine();
        return;
    }
Robin
  • 21
  • 3
  • 1
    The answer is `Random.Next()` is not thread safe. – NetMage Apr 29 '22 at 19:57
  • *It appears to be a very theoretical and even weird question* - up to that point you haven't actually asked a question. The only question you've actually even ended up asking is "can anyone imagine how..", the answer to which is "yes". Please collect your thoughts and refine your question – Caius Jard Apr 29 '22 at 19:58
  • @CaiusJard Netmage has given a reasonable answer, and I found that one of the answers in "https://stackoverflow.com/questions/3049467/is-c-sharp-random-number-generator-thread-safe" helps to understand what happens and how to improve potential problems. It seems you always 100% clearly know what you want to know and one is supposed not to have a very theoretical question nor have a weird question. Lucky you. Isn't that so strange many people already thought about similar concerns and have some idea how to handle it? – Robin May 01 '22 at 13:14

0 Answers0