C# enque random int - PullRequest
       17

C# enque random int

0 голосов
/ 04 апреля 2020

У меня есть три потока, которые, как предполагается, добавляют случайное int в очередь, четвертый, который извлекает int, и пятый, который печатает числа внутри него. Я использую потоки, потому что они в конечном итоге понадобятся для целей этой программы и для постановки в очередь / удаления из очереди большего числа чисел, но возникают проблемы с генерацией случайного целого числа. Я использую класс RandomGenerator для создания числа, и создаю экземпляр этого класса, затем вызываю его метод GetRandom, чтобы установить в поле int случайное число. Затем я передаю это поле в первые три потока, которые вызывают метод для постановки в очередь. Int, который печатает, не является случайным, и я понимаю, что это потому, что я просто вызываю метод в начале программы и передаю одно и то же точное число всем трем потокам. Я относительно новичок в C# и понимаю, что могу совершить основную ошибку c. Я также понимаю, что четвертый поток иногда обращается к очереди, когда она пуста, но в данный момент это не так важно. Я пробовал несколько разных вещей с этим и мог также иметь генератор чисел в классе Program. Вот код:

...

class Program
{
    static void Main()
    {
        Program p = new Program();
        RandomGenerator rg = new RandomGenerator();

        Queue<int> numberQueue = new Queue<int>();

        int randomNumber = rg.GetRandom(1, 10);

        Thread T1 = new Thread(delegate () { p.EnqueueNumber(numberQueue, randomNumber); });
        Thread T2 = new Thread(delegate () { p.EnqueueNumber(numberQueue, randomNumber); });
        Thread T3 = new Thread(delegate () { p.EnqueueNumber(numberQueue, randomNumber); });
        Thread T4 = new Thread(delegate () { p.DequeueNumber(numberQueue); });
        Thread T5 = new Thread(delegate () { p.PrintNumbers(numberQueue); });

        T1.Start();
        T2.Start();
        T3.Start();
        T4.Start();
        T5.Start();

        T1.Join();
        T2.Join();
        T3.Join();
        T4.Join();
        T5.Join();
    }

    public void EnqueueNumber(Queue<int> numberQueue, int randomNumber)
    {
        numberQueue.Enqueue(randomNumber);
    }

    public void DequeueNumber(Queue<int> numberQueue)
    {
        numberQueue.Dequeue();
    }

    public void PrintNumbers(Queue<int> numberQueue)
    {
        foreach (int i in numberQueue)
        {
            Console.Write(i);
        }

        Console.ReadKey();
    }
}

public class RandomGenerator
{
    private static Random _random = new Random();
    private static object syncLock = new object();

    public int GetRandom(int min, int max)
    {
        lock (syncLock)
        {
            return _random.Next(min, max);
        }
    }
}

...

1 Ответ

2 голосов
/ 04 апреля 2020

Вы передаете возвращаемое значение метода GetRandom() вашего единственного RandomGenerator экземпляра каждому из потоков.

Вам необходимо передать ссылку * Вместо 1008 * до RandomGenerator для каждого из потоков, поэтому каждый раз можно вызывать GetRandom().

Thread T1 = new Thread(delegate () { p.EnqueueNumber(numberQueue, rg); });

Если вы создаете RandomGenerator для каждого потока, вы также можете прекратить использовать блокировки, которые Избыточность для этого варианта использования.

Наконец, если вы настаиваете на одновременной множественной записи, однократном чтении из одной и той же очереди, вам также следует обратить внимание на ConcurrentQueue , а не на Queue, поскольку он является потоком -safe.

...