C# 查询随机整数

C# enque random int

我有三个线程应该将一个随机整数添加到队列中,第四个线程将一个整数从队列中取出,第五个线程打印其中的数字。我正在使用线程,因为最终将需要它们用于该程序的范围和 enqueue/dequeue 更多的数字,但在生成随机 int 方面存在问题。我正在使用 class RandomGenerator 来创建数字,并创建此 class 的实例,然后调用其 GetRandom 方法将 int 字段设置为随机数。然后我将这个字段传递给前三个线程,这三个线程调用该方法进行排队。打印的 int 不是随机的,我意识到这是因为我只是在程序开始时调用该方法并将相同的确切数字传递给所有三个线程。我是 C# 的新手,意识到我可能犯了一个基本错误。我还意识到第四个线程有时会在队列为空时访问队列,但目前并不那么重要。我已经尝试了很多不同的东西,也可以在程序 class 中使用数字生成器。这是代码:

...

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);
        }
    }
}

...

您正在将单个 RandomGenerator 实例的 GetRandom() 方法的 return 传递给每个线程。

您需要将 reference 传递给每个线程 RandomGenerator,这样每次都可以调用 GetRandom()

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

如果你为每个线程创建一个 RandomGenerator,你也可以停止使用锁,这对于这个用例来说太过分了。

最后,如果您坚持从同一个队列中同时进行多写入、单读取,您还应该查看 ConcurrentQueue 而不是队列,因为它是线程安全的。