3

I need to run the following method in 100 different threads simultaneously but i cant seem to get it done beacause when I try with only two threads it generates the same random numbers for both. Is there a thread safe method where i can get a random number between two set numbers? I remember I was able to do so in Java using ThreadLocalRandom.current().nextInt() but I cant seem to find the equivalent in c#.

public void iniciarSupermercado()
    {



        Random random = new Random();

        tiempoEntrada = random.Next(300, 600 + 1);
        Thread.Sleep(tiempoEntrada);
        Console.WriteLine("Ha entrado el cliente (Duracion: " + tiempoEntrada + ")");

        cantPasillos = random.Next(8, 13 + 1);
        Console.WriteLine("CLiente va a buscar " + cantPasillos + " pasillos");

        while (cantPasillos > 0)
        {

            cantProdPasillo = random.Next(0, 6 + 1);
            Console.WriteLine(cantProdPasillo + " productos encontrados en pasillo: " + cantPasillos);
            totalProductosCliente = totalProductosCliente + cantProdPasillo;

            while (cantProdPasillo > 0)
            {

                tiempoProducto = random.Next(20, 80 + 1);
                Thread.Sleep(tiempoProducto);

                cantProdPasillo--;


            }



            cantPasillos--;

        }

        Console.WriteLine("Productos : " + totalProductosCliente);

        Console.WriteLine("Cliente progresa al cajero");
        productosCajero = totalProductosCliente;

        while (productosCajero > 0)
        {

            tiempoProdCajero = random.Next(20, 80 + 1);
            productosCajero--;

        }

        Console.WriteLine("El clienta ha comprado " + totalProductosCliente + "y ha estado en el supermercado");
        Console.Read();
    }


}

Sorry for my bad writing, english is not my first language.

  • 3
    Does this answer your question? [Is C# Random Number Generator thread safe?](https://stackoverflow.com/questions/3049467/is-c-sharp-random-number-generator-thread-safe) – MoonMist Dec 09 '19 at 03:55
  • Can you show the code for multithreading? – Tarik Dec 09 '19 at 03:56
  • 1
    Your problem has nothing to do with the thread safety. All instances of `Random` are just initialized with the same seed because default constructor uses ticks for that and for the threads started at the the same time good chances that the ticks value isn't updated. You either need using custom seed ( virtual number of thread, etc.) or single shared instance of `Random` for all of your threads. – Dmytro Mukalov Dec 09 '19 at 06:51

1 Answers1

1

The problem isn't multi-threading, it's using the default constructor: new Random().

If you call your method four times in succession, there's a great chance all of those Random instances will get the same seed, and thus generate the same sequence of numbers. You need to get a seed from the outside to give you some randomness; one easy way would be something like this:

var seedGenerator = new Random();
for (var i = 0; i < 4; i++)
{
  var seed = seedGenerator.Next();
  // Launch each of the tasks however you want
  Task.Run(() => iniciarSupermercado(seed));
}

and passing the seed value to the Random constructor inside iniciarSupermercado.

If you want avoid relying on getting the seed from your caller, another option would be to have a synchronized Random instance to provide the seed. Something like this will work fine:

public static SlowRandom
{
  private static readonly syncObject = new object();
  private static readonly Random generator = new Random();

  public static int Next()
  {
    lock (syncObject) return generator.Next();
  }
}

This will give you a seed any time you want, from any thread you want. Just make sure you don't use it a million times a second :)

Luaan
  • 62,244
  • 7
  • 97
  • 116